You're right. There is a simpler way.
First of all, instead of giving every interactive element its own method, let's give them all the same method.
- (IBAction)buttonPressed:(id)sender;
If they're not all buttons, a different method name is in line, but for this example, I'll assume them all to be buttons.
Now then, whether you're creating these UI elements programmatically or via interface builder, the next important step is to give each element its own unique tag. In the Interface Builder, this is done under the "Attributes Inspector" (the icon that looks like a shield). The "tag" field is the second field under the "View" heading. It doesn't matter what tag you give the button. It only matters that the tags are unique.
Setting the tag programmatically is as simple as this:
myButton.tag = 100;
Now, instead of a different method for each button (or other UI element), we can simply use a single button:
- (IBAction)buttonPressed:(id)sender {
[self.delegate someRequiredMethod:sender.tag];
}
Now we've condensed your code. But we can do even better.
Let's create an enum
so that we're not just sending arbitrary numbers, but instead we send values that the delegate can make more sense of (and if using a switch
, Xcode will help the delegate be sure he accounts for every case).
typedef NS_ENUM(NSInteger, MyExampleButtonEnum) {
ButtonIndexUnknown = 0,
ButtonIndexTopLeft = 100,
ButtonIndexTopRight = 101,
ButtonIndexBottomLeft = 102,
ButtonIndexBottomRight = 103
};
This should be placed in the .h
and before our @protocol
. Then we can change our protocol to look like this instead:
@protocol MyExampleProtocol <NSObject>
@required
- (void)someRequiredMethod:(MyExampleButtonEnum)button;
@end
Now we just have to set our button tags to match these enum values. The good news is, if we're doing it programmatically, we can use the enum itself to set the values. For example...
UIButton *topLeftButton = [[UIButton alloc] initWithFrame:someFrame];
topLeftButton.tag = ButtonIndexTopLeft;
[topLeftButton addTarget:self action:@selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside]
And now we slightly modify our buttonPressed:
method as such:
- (IBAction)buttonPressed:(id)sender {
if (sender) {
[self.delegate someRequiredMethod:sender.tag];
} else {
[self.delegate someRequiredMethod:ButtonIndexUnknown];
}
}
And our delegate can implement the delegate method in some fashion like this:
- (void)someRequiredMethod:(MyExampleButtonEnum)button {
switch(button) {
case ButtonIndexTopLeft:
// do stuff
break;
case ButtonIndexTopRight:
// do stuff
break;
case ButtonIndexBottomLeft:
// do stuff
break;
case ButtonIndexBottomRight:
// do stuff
break;
case ButtonIndexUnknown:
default:
// do stuff
break;
}
}