An enhancement for UIAlertView

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:

RSAlert* alert = [[RSAlert alloc] initWithTitle: @“Title” message: @“Message!” target: self selector: @selector(dismissedAlert:buttonIndex:) cancelButtonTitle: @“OK” otherButtonTitles: nil];

 

and handle the result with a selector, similar to NSAlert:

 (void) dismissedAlert: (RSAlert*) alert buttonIndex: (NSInteger) buttonIndex
{
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