Silver Challenge: (id)sender: what is it?

#1

Hi there,

I worked hard on this challenge, but couldn’t figure out myself how to implement the method to choose the color.

So the code would be something like that:

-(void)chooseColor:(id)sender
{
    UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
    NSString *controlSelected = [segmentedControl titleForSegmentAtIndex:[segmentedControl selectedSegmentIndex]];
    
    UIColor *colorSelected;
        
    if ([controlSelected isEqualToString:@"Red"]) {
        NSLog(@"Index selected: %@", controlSelected);
    } else if ([controlSelected isEqualToString:@"Green"]) {
        colorSelected = [UIColor greenColor];
    } else if ([controlSelected isEqualToString:@"Blue"]) {
        colorSelected = [UIColor blueColor];
    }
    
        self.backgroundView.circleColor = colorSelected;
}

What I don’t understand is:
-Why and how do we know that the method to invoke is -(void)chooseColorOrWhatever:(id)sender?
-Then let’s say we figured that out, what is the first line of the code: UISegmentedControl *segmentedControl = [color=#FF0000](UISegmentedControl *)sender;[/color]?

Did I miss a chapter ?
Thanks !

#2

OK I understood, (id)sender make you able to choose any kind of type you want in your method.
But as we know that we want a UISegmentedControl and nothing else, I changed a little bit the code, and here is what I did:

BNRHypnosisView

@interface BNRHypnosisView : UIView

@property (nonatomic, strong) UIColor *circleColor;

@end

BNRHypnosisViewController

@interface BNRHypnosisViewController()

@property (nonatomic, weak) BNRHypnosisView *backgroundView;
@property (nonatomic, weak) UISegmentedControl *colorChoice;

-(void)addSegmentedControl;
-(void)chooseColor:(UISegmentedControl *)colorChoice;

@end

@implementation BNRHypnosisViewController

-(instancetype)initWithNibName:(NSString *)nibNameOrNil
                        bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil
                           bundle:nibBundleOrNil];
    if (self) {
        //Set the tab bar item's title
        self.tabBarItem.title = @"Hypnotize";
        
        //Create a UIImage from a file
        //This will use Hypno@2x.png on retina display devices
        UIImage *i = [UIImage imageNamed:@"Hypno.png"];
        
        //Put that image on the tab bar item
        self.tabBarItem.image = i;   
    }
    return self;
}

-(void)loadView
{
    //Create a view
    BNRHypnosisView *mainView = [[BNRHypnosisView alloc] init];

    //Set it as *the* view of this view controller
    self.backgroundView = mainView;
    self.view = self.backgroundView;
    [self addSegmentedControl];
}

-(void)addSegmentedControl
{
    UISegmentedControl *colors = [[UISegmentedControl alloc] initWithItems:@[@"Red", @"Blue", @"Green"]];
    colors.frame = CGRectMake(80, 30, 160, 30);
    colors.momentary = YES;
    colors.backgroundColor = [UIColor whiteColor];
    
    self.colorChoice = colors;
    
    [self.colorChoice addTarget:self
                         action:@selector(chooseColor:)
               forControlEvents:UIControlEventValueChanged];
    
    [self.backgroundView addSubview:self.colorChoice];   
}

-(void)viewDidLoad
{
    //Always call the super implementation of viewDidLoad
    [super viewDidLoad];
    
    NSLog(@"BNRHypnosisViewController loaded its view.");
}

-(void)chooseColor:(UISegmentedControl *)colorChoice
{
    NSString *controlSelected = [colorChoice titleForSegmentAtIndex:[colorChoice selectedSegmentIndex]];
    
    UIColor *colorSelected;
        
    if ([controlSelected isEqualToString:@"Red"]) {
        NSLog(@"Index selected: %@", controlSelected);
        colorSelected = [UIColor redColor];
    } else if ([controlSelected isEqualToString:@"Green"]) {
        NSLog(@"Index selected: %@", controlSelected);
        colorSelected = [UIColor greenColor];
    } else if ([controlSelected isEqualToString:@"Blue"]) {
        NSLog(@"Index selected: %@", controlSelected);
        colorSelected = [UIColor blueColor];
    }
        self.backgroundView.circleColor = colorSelected;
}
@end

And that’s it ! Working perfectly well for now… glad I could use some help from all of you to complete this challenge, thanks !