Question

It's great to be able to addTarget on a UIButton. I only wish there was some sneaky way I could attach state to the UIButton so that when the target method is invoked, I could magically pull that state (any id) from the sender.

Something like:

[button shoveMyObjectInThere:foo];
[button addTarget:self action:@selector(touchyTouchy:) forControlEvents:UIControlEventTouchUpInside];

Followed by:

-(void) touchyTouchy:(id) sender {
    UIButton button = (UIButton*)sender;
    id foo = [button getByObjectBack];
    // do something interesting with foo
}

Would be great if UIButton had an 'id context' property where developers could shove stuff, but that doesn't seem to be the case. Objective-C is a very dynamic language though, so I wonder if there is some sneaky way I can add method or fields to an object at runtime?

Was it helpful?

Solution

You could try making an associative reference

#import <objc/runtime.h>

objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy); 
objc_getAssociatedObject(id object, void *key);

OTHER TIPS

What about something like setValue:forKey:, a part of the Key-Value coding feature of Objective-C?

So I just did a quick test and found some interesting results.

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:@"Hello" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(100, 100, 100, 100);
[self.window addSubview:button];

// ...

- (void)buttonClicked:(id)sender {
    NSLog(@"button clicked %@", [sender class]);
}

This prints: button clicked UIRoundedRectButton

So it seems like this should be possible... Truth be told, I ran into some problems subclassing UIButton to get the full example working but this seems promising. :)

The official solution is to use the "tag" property:

[self.someMutableArray addObject:foo];
button.tag = self.someMutableArray.count - 1;

[button addTarget:self action:@selector(touchyTouchy:) forControlEvents:UIControlEventTouchUpInside];

Then:

-(void) touchyTouchy:(id) sender {
    UIButton button = (UIButton*)sender;
    id foo = self.someMutableArray[button.tag];
    // do something interesting with foo
}

In most situations you'd use an enum or constant for the tag, but an array is obviously more flexible.

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