Jaicob
Jaicob

Reputation: 60

iOS subview best practice

so here is what i've got; A ViewController with a root UIView(subclass) that has one subview that is a UISegmentedControl. The UIView draws concentric circles, and the UISegmentedControl changes the color of those circles. In order to do this I created my UIView in my ViewControllers loadView and added it to self.view, then I made the UISegmentedControl and added it as a subview of my UIView. Then I set the UIView as the target of the UISegmentControl and implemented a method in UIView to change the color and set that as the action. and this all works.

some code for reference

//setting up view hierarchy in viewcontroller.m

- (void)loadView{
    BNRHypnosisView *backgroundView = [[BNRHypnosisView alloc]init];
    self.view = backgroundView;
    UISegmentedControl *segmentedControl = [[UISegmentedControl alloc]initWithItems:@[@"Red",@"Green",@"Blue"]];
    [segmentedControl addTarget:backgroundView
                         action:@selector(changeColor:)
               forControlEvents:UIControlEventValueChanged];
    [backgroundView addSubview:segmentedControl];
  }


//action
 - (void)changeColor:(UISegmentedControl *)sender{

      switch (sender.selectedSegmentIndex) {
        case 0:
          self.circleColor = [UIColor redColor];
          break;

        case 1:
          self.circleColor = [UIColor greenColor];
          break;

        case 2:
          self.circleColor = [UIColor blackColor];
          break;
      }
    }

So for my question...Here I am treating the super view as the controller of my subview, is this wrong? should leave everything to be handled by the view controller that owns my UIView. If so how could I do that in this situation?

-Thanks

and incase anyone picked up on it yes, this is one of the challenges from BNR iOS programming book :]

Upvotes: 0

Views: 308

Answers (1)

Pfitz
Pfitz

Reputation: 7344

In MVC this is wrong. As you said you make a view to a controller and this never should be. Your aim should be to make most of your classes independent of other classes (loose coupling).

In your case you should move all code and especially the target action code to the view controller. Change the action to target the viewController in viewDidLoad:

[segmentedControl addTarget:self
                     action:@selector(changeColor:)
           forControlEvents:UIControlEventValueChanged];
[backgroundView addSubview:segmentedControl];

and move the changeColor method to the view controller and cast the sender of the method to a UISegmented control:

- (void)changeColor:(id)sender{

     UISegmentedControl *segControl = (UISegmentedControl *) sender;

      switch (segControl.selectedSegmentIndex) {
        case 0:
          circleView.circleColor = [UIColor redColor];
          break;

        case 1:
          circleView.circleColor = [UIColor greenColor];
          break;

        case 2:
          circleView.circleColor = [UIColor blackColor];
          break;
      }
    }

for this to work you need to have a property to your circleView therefore make a property in the view controller and when creating the circleView assign it to the property.

@proprety (nonatomic, strong) BNRHypnosisView *circleView;

and in your loadView: method:

- (void)loadView{
    self.circleView = [[BNRHypnosisView alloc]init];
    self.view = self.circleView;

Upvotes: 1

Related Questions