Adding context to a UI control or NSObject
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 U开发者_开发技巧IButton 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?
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);
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.
精彩评论