I am looking for a class that has an "event list" similar to how UIButton works where you can add multiple targets and selectors.
It's easy enough to write one, but if Apple has already provided a solution I would rather use this than have more code to maintain.
Note:
This is for a non-visual class, so I don't really want to use any of the UI specific stuff.
Edit:
I ended up rolling my own rudimentary event dispatcher type class using stacked NSDictionary instances.
@implementation ControllerBase
@synthesize eventHandlers;
- (id) init
{
self = [super init];
if (self!=NULL)
{
NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
[self setEventHandlers: dict];
[dict release];
}
return self;
}
-(void) addTarget: (id) target action:(SEL) selector forEvent:(NSString*) eventName
{
NSString* selectorString = NSStringFromSelector(selector);
NSMutableDictionary* eventDictionary = [eventHandlers objectForKey:eventName];
if (eventDictionary==NULL)
{
eventDictionary = [[NSMutableDictionary alloc] init];
[eventHandlers setValue:eventDictionary forKey:eventName];
}
NSArray* array = [NSArray arrayWithObjects:selectorString,target, nil];
[eventDictionary setValue:array forKey: [target description]];
}
-(void) removeTarget: (id) target action:(SEL) selector forEvent:(NSString*) eventName;
{
NSMutableDictionary* eventDictionary = [eventHandlers objectForKey:eventName];
//must have already been removed
if (eventDictionary!=NULL)
{
//remove event
[eventDictionary removeObjectForKey:target];
//remove sub dictionary
if ([eventDictionary count]==0)
{
[eventHandlers removeObjectForKey:eventName];
[eventDictionary release];
}
}
}
-(void) fireEvent:(NSString *)eventName
{
NSMutableDictionary* eventDictionary = (NSMutableDictionary*) [eventHandlers objectForKey:eventName];
if (eventDictionary!=NULL)
{
for(id key in eventDictionary)
{
NSArray* eventPair= [eventDictionary valueForKey:key];
if (eventPair!=NULL)
{
NSString* selectorString = (NSString*)[eventPair objectAtIndex:0];
//remove colon at end
SEL selector = NSSelectorFromString ( [selectorString substringWithRange: NSMakeRange(0, [selectorString length]-1)] ) ;
id target = [eventPair objectAtIndex:1];
[target performSelector:selector];
}
}
}
}
-(void) dealloc
{
for(id key in eventHandlers)
{
NSMutableDictionary* eventDictionary = (NSMutableDictionary*) [eventHandlers objectForKey:key];
for(id key in eventDictionary)
{
[eventDictionary removeObjectForKey:key];
}
[eventDictionary release];
}
[eventHandlers release];
[super dealloc];
}
@end
UIButton
is a subclass of UIControl
. UIControl
manages the target/action list for each control event. It has a predefined set of control events, like UIControlEventTouchUpInside
and UIControlEventValueChanged
. Each control event is represented by a bit in a mask. The bitmask has four bits reserved for app-defined events (UIControlEventApplicationReserved = 0x0F000000
).
If UIControl
doesn't do what you want, you'll need to roll your own event management.