Silver Challenge (not using switch/case)


#1

I’ve seen a few other people using CASE a lot. Don’t use CASE or SWITCH unless there is no other way. Usually there is a better way.

HypnosisViewController.h needs no changes.

HypnosisViewController.m
You need to first declare an array of titles for the segment buttons.
Then you must make a segmented control, using the button titles in the array.
You must declare the method that gets called when the segmented control button is pushed. In my case I made a new method in the HypnosisView class to do this for me.
Then make a rect to draw the segmented button in.
Add it as a subview. This is building on the previous chapters and challenges so far.

@implementation HypnosisViewController

-(void)loadView
{
    CGRect frame = [[UIScreen mainScreen] bounds];
    HypnosisView *v = [[HypnosisView alloc] initWithFrame:frame];
    [self setView:v];
    
//SILVER CHALLENGE
    //declare array of text to label the button bar
    NSArray *colorArray = [NSArray arrayWithObjects:@"Red", @"Green", @"Blue", nil];
    //create button bar
    UISegmentedControl *segBar = [[UISegmentedControl alloc] initWithItems:colorArray];
    //declare button actions
    [segBar addTarget:v
               action:@selector(setCircleColorViaText:)
     forControlEvents:UIControlEventValueChanged];
    //create a default size and placement
    CGRect segBox = CGRectMake(10, 10, 300, 40);
    //add a subview to the view
    [segBar setFrame:segBox];
    [v addSubview:segBar];
//END SILVER CHALLENGE
}

HypnosisView.h
Here we need to declare an iVar for the array of UI colors I will use later. I made it strong so it’s not destroyed prematurely.
I also declared the new method I am using via the button.

[code]@interface HypnosisView : UIView
{
//SILVER CHALLENGE IVAR ADDED, strong so it stays around
__strong NSArray *optionalColors;
}

@property (nonatomic, strong) UIColor *circleColor;

//SILVER CHALLENGE METHOD DECLARATION
-(void)setCircleColorViaText:(id)sender;

@end
[/code]

HypnosisView.m
Here I created a new method that the seg button calls.
There is no need for case. I first create the NSArray with the UIColors as the array objects.
When the button is pressed, I use the selected segment property of the sender (the button) to correspond it to the UI color in the array.
This of course assumes you can keep the array in the same order as your buttons, and those 2 things are in different classes. Using SWITCH/CASE would eliminate the coordination of order of string array and UIColor array, but still seems so much more clunky.

[code]-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
[self setBackgroundColor:[UIColor clearColor]];
[self setCircleColor:[UIColor lightGrayColor]];

//SILVER CHALLENGE ARRAY ADDED
optionalColors = [NSArray arrayWithObjects:[UIColor redColor], 
                  [UIColor greenColor], [UIColor blueColor], nil];

return self;

}

-(BOOL)canBecomeFirstResponder
{
return YES;
}

//SILVER CHALLENGE METHOD
-(void)setCircleColorViaText:(id)sender
{
NSLog(@“sender button, %d”, [sender selectedSegmentIndex]);
[self setCircleColor:[optionalColors objectAtIndex:[sender selectedSegmentIndex]]];
}
//END SILVER CHALLENGE[/code]

There may be some better ways to handle this, but it works for me.
Chris


#2

Not saying that your implementation is bad, however using a switch/case or if/then/else statement allows the program to grow in functionality. If later edits to the project requires a combination of steps to be done based upon the segment selected and each segment performed a different set of instructions, it would be easier to change/implement with a control block in place.


#3

In this case - I believe switch / case, is the better way to go here.
Your solution works - but if we wanted to grow the program - a lot of effort is required. More than needed.


#4

[quote=“Tander”]In this case - I believe switch / case, is the better way to go here.
Your solution works - but if we wanted to grow the program - a lot of effort is required. More than needed.[/quote]

I agree.

Plus I prefer the UISegmentedControl to target the HypnoViewController (closer to the MVC paradigm I think).

Can someone tell me why the switch - case should be avoided in this case ?


#5

So to clarify - why the suggestion to avoid switch statements? Performance?