Silver Challenge : Is it wrong to ...?


#1

Hello,

For the silver challenge i went ahead and added the UISegementedControl directly on HypnosisView like so:

HypnosisView.h

#import <Foundation/Foundation.h>

@interface HypnosisView : UIView
{
    UISegmentedControl *segmentedControl;
}
@property (nonatomic, strong) UIColor *circleColor;
@end

HypnosisView.m


...

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if(self)
    {
        [self setBackgroundColor:[UIColor clearColor]];
        
        
        NSArray *options = [NSArray arrayWithObjects:@"Red",@"Green",@"Blue", nil];
        segmentedControl = [[UISegmentedControl alloc] initWithItems:options];
        [self addSubview:segmentedControl];
        [segmentedControl setFrame:CGRectMake((frame.size.width / 2) - (segmentedControl.frame.size.width / 2), 20, segmentedControl.frame.size.width, segmentedControl.frame.size.height)];
        
        [self setCircleColor:[UIColor redColor]];
        [segmentedControl setSelectedSegmentIndex:0];
        [segmentedControl addTarget:self
                             action:@selector(onSegmentedControlPressed:)
                   forControlEvents:UIControlEventValueChanged];
    }
    return self;
}

-(void)onSegmentedControlPressed:(id)sender
{
    if([segmentedControl selectedSegmentIndex] == 0)
    {
        [self setCircleColor:[UIColor redColor]];
    }
    else if([segmentedControl selectedSegmentIndex] == 1)
    {
        [self setCircleColor:[UIColor greenColor]];
    }
    else
    {
        [self setCircleColor:[UIColor blueColor]];
    }
    
}

...

Everyone else seems to have added it to the controller and not to the view. My code works well, but i am wondering if it’s conceptually wrong or something. Sorry if this is a dumb question!

Thanks!


#2

I think this becomes an issue of scope, what do you need access to from where and how. Without knowing anything further than this chapter, I would say an issue presents itself if you have hypnosisViewController having multiple subviews of HypnosisView. In such a situation, your implementation would cause a separate UISegmentedControl to be placed on each of the subviews. The question then pops up as to what does the program want the segmented control to do. Does it want to change the colors of all the hypnosis view or just the currently active one. If you place the segmented control in hypnosisViewController you can tell it to change each of the subviews since that’s where your action controls are. I’m not too sure how it would be done in your implementation.


#3

What you say makes sense. I guess this becomes a “it depends” question.

Thanks for the reply.


#4

donPiter,

While the placement of view related code is still somewhat of a mystery to me, i.e. does it go in loadView, viewDidLoad, viewWillLoad, or an init method? the general answer seems to be “loadView”. The only available loadView method is in a UIViewController so, that’s where the segmentedControl code goes. The init method only gets called once so you run the risk of having the additional views being swapped out at some point and not recreated. Possibly due to low memory, backgrounded or rotation related changes.
The UIViewController manages the view and subviews and will call loadView when necessary. I think it’s also possible when using loadView you don’t need to hang on to an instance variable.

Rules I’ve picked up so far:
-init
can place navigationItem related code here (like adding barbuttonitems) because it has to be present before the view is displayed in order to show up on the navigation bar.
-loadView:
documentation says to create subviews and other stuff like that here
-viewDidLoad
more opportunity to customize the views and subviews