I like objective-c protocols, and I am a fan of the interface oriented designs that it allows for. But, sometimes the indirection of using a selector with a defined signature just works better, and the problem is that UIAlertView does not take a selector. Instead, UIAlertView defines a protocol, UIAlertViewDelegate, that the alert’s delegate adopts to receive notification of the user intent. To be fair, UIAlertView communicates a bit more information back to it’s delegate than the target of an NSAlert, and the UIAlertViewDelegate protocol does a fine job achieving that goal. 99% of the time, however, I want to show an alert and have it call my named selector when it is done. To that end, I finally busted out the admittedly tiny class that does the job.
Now in my client code I show an alert like this:
and handle the result with a selector, similar to NSAlert:
{
NSLog(@“dismissedStartupAlert with buttonIndex: %d”, buttonIndex);[alert autorelease];
}
I realize this is an infinitesimally small annoyance, but sometimes it’s the little things that keep us happy.
RSAlert.h
#import
@interface RSAlert : NSObject
{
UIAlertView* alertView_;
id target_;
SEL selector_;
}
– (id)initWithTitle: (NSString*) title
message: (NSString*) message
target: (id) target
selector: (SEL) selector
cancelButtonTitle: (NSString*) cancelButtonTitle
otherButtonTitles: (NSString*) otherButtonTitles, …;
– (void) show;
@end
RSAlert.m
#import “RSAlert.h”
@implementation RSAlert
– (id)initWithTitle: (NSString*) title
message: (NSString*) message
target: (id) target
selector: (SEL) selector
cancelButtonTitle: (NSString*) cancelButtonTitle
otherButtonTitles: (NSString*) otherButtonTitles, …;
{
self = [super init];
if ( self )
{
target_ = [target retain];
selector_ = selector;
alertView_ = [[UIAlertView alloc] initWithTitle: title
message: message
delegate: self
cancelButtonTitle: cancelButtonTitle
otherButtonTitles: nil];
if ( otherButtonTitles )
{
va_list argList;
id anArg;
[alertView_ addButtonWithTitle: otherButtonTitles];
va_start(argList, otherButtonTitles);
while ( anArg = va_arg(argList, id) )
{
[alertView_ addButtonWithTitle: anArg];
}
va_end(argList);
}
}
return self;
}
– (void) dealloc
{
[target_ release];
[alertView_ release];
[super dealloc];
}
– (void) show
{
[alertView_ show];
}
– (void) alertView: (UIAlertView*) alertView
clickedButtonAtIndex: (NSInteger) buttonIndex
{
// Do nothing
}
– (void) alertViewCancel: (UIAlertView*) alertView
{
[target_ performSelector: selector_
withObject: self
withObject: (id) 0];
}
– (void) willPresentAlertView: (UIAlertView*) alertView
{
// Do nothing
}
– (void)didPresentAlertView: (UIAlertView*) alertView
{
// Do nothing
}
– (void) alertView: (UIAlertView*) alertView
willDismissWithButtonIndex: (NSInteger) buttonIndex
{
// Do nothing
}
– (void) alertView: (UIAlertView*) alertView
didDismissWithButtonIndex: (NSInteger) buttonIndex
{
[target_ performSelector: selector_
withObject: self
withObject: (id) buttonIndex];
}
@end