Question

I have a view containing a number of UIButtons "Tom and Jerry", "The Lion King", etc. I want all of them to invoke the same action in my view controller, and then differentiate between the different buttons to get a button-specific NSString (e.g. identifiers like "TomJerry", "LionKing").

Ideas:

  1. Abuse buttons' title text property (custom button style, clear text color).
    • Would work, but feels dirty… (and only works if the button doesn't need to display text.)
  2. Subclass UIButton with an extra ivar + property "context".
    • Great for adding the buttons programmatically,
    • but: my view is loaded from a Nib, so I would have to define an outlet for every button (and set its context property in awakeFromNib or viewDidLoad). Bleh…
  3. Create a subclass for each button with different "-(NSString*)context" method implementations.
    • Ugh… seriously? ;-)
  4. Use tags to identify buttons and a dictionary for mapping tags to button-specific strings.
    • DRY violation: The tag would need to be known/specified twice – in the Nib to identify the button, and in the dictionary to retrieve the corresponding string.
    • I have thus far avoided using tags. Maybe this would be a good opportunity to start?

How best to achieve this? Any ideas, best-practices, implementation patterns?


Update: After reading the first answers (thanks!), I believe I should add some points for clarification.

All of the above approaches should work; point is, I don't particularly like any of them. I am asking you which of the approaches you would favor (and why), or whether there are other better approaches.

Further "requirements":

  • I don't want to connect each button as an outlet.
  • I want to retrieve the button-specific string in a generic fashion, i.e. no switch on the action sender à la if (sender==self.button1) {…} else if (sender==self.button2) {…}
Was it helpful?

Solution

Added
An option would be to create a category of UIButton adding a method that returns an NSString based on the tag. You've still got the potential tag trouble but the tag-to-string conversion -- actual and conceptual -- is all in one place.

I believe this meets your original and further requirements.


Previously
Tags are fast and light, comparing two integers.

You can easily create a numbering scheme that keeps things cleanly separated: 1000-1999 is this type of thing, 1000-1099 is this subgroup, 1015 is an instance, etc.

Numeric comparisons are available: x.tag > 10000 do this.

Obviously, though, that means you have to track it and your code could end up difficult to parse down the road. Still, some nifty advantages.

OTHER TIPS

You can compare the button reference in button handler.

IBOutlet UIButton *button1;
IBOutlet UIButton *button2;

-(IBAction)myButtonHanlder:(id)sender {
    if (sender == button1) {
        // do task for button1
    } else if (sender == button2) {
        // do task for button2
    }
}

NOTE: I have not compiled the code. But I guess you have got the idea.

My comment about your ideas are:

  1. It is very natural to change the title text, color etc. Button work flow should not be so much dependent on the view style.

  2. Subclassing UIButton for just this compare is too much of work.

  3. This is ever dirtier version of 2.

  4. Well, you need to be very careful that you have not used same tag for two different button.

For this context, the best way is to create a subclass of UIButton class, and add a property like index or any other properties that will be useful to you.

or else

while creating buttons assign some tags to them, based on the tag you can differentiate them and you can perform whatever action that you want.

Regards,

Satya

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top