Block-based UIAlertViews
Using UIAlertViews gets a bit annoying. You basically have to instantiate one and configure it, set its delegate to something that implements the UIAlertViewDelegate protocol. After that, you have to implement a method that gets called by the alert view when the user taps a button, and handle the button press.
However! If you’re developing for iOS 4 or later, you now have the ability to use blocks. Here’s a subclass of UIAlertView that allows you to use a block for a callback rather than having to worry about delegation.
ACAlertView.h
//
// ACAlertView.h
//
// Created by Anshu Chimala on 7/30/10.
// Copyright 2010 Anshu Chimala. All rights reserved.
//
@interface ACAlertView : UIAlertView {
void(^buttonTapHandler)(NSInteger buttonIndex);
}
@property (copy) void(^buttonTapHandler)(NSInteger buttonIndex);
- (id)initWithTitle:(NSString *)title message:(NSString *)message buttonTapHandler:(void(^)(NSInteger buttonIndex))handler;
+ (ACAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message buttonTapHandler:(void(^)(NSInteger buttonIndex))handler;
@end
ACAlertView.m
//
// ACAlertView.m
//
// Created by Anshu Chimala on 7/30/10.
// Copyright 2010 Anshu Chimala. All rights reserved.
//
#import "ACAlertView.h"
@implementation ACAlertView
@synthesize buttonTapHandler;
- (id)initWithTitle:(NSString *)title message:(NSString *)message buttonTapHandler:(void(^)(NSInteger buttonIndex))handler {
if((self = [super init])) {
self.title = title;
self.message = message;
self.buttonTapHandler = handler;
self.delegate = self;
}
return self;
}
+ (ACAlertView *)alertWithTitle:(NSString *)title message:(NSString *)message buttonTapHandler:(void(^)(NSInteger buttonIndex))handler {
return [[[ACAlertView alloc] initWithTitle:title message:message buttonTapHandler:handler] autorelease];
}
- (void)dealloc {
self.buttonTapHandler = nil;
[super dealloc];
}
#pragma mark -
#pragma mark UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
buttonTapHandler(buttonIndex);
}
@end
So how exactly does this work? Here’s an example:
ACAlertView *alert = [ACAlertView alertWithTitle:@"Destroy the universe?" message:@"This is serious business." buttonTapHandler:^(NSInteger buttonIndex) {
if(buttonIndex == 0)
[[NSUniverse sharedUniverse] destroy];
}];
[alert addButtonWithTitle:@"Hell yeah"];
[alert addButtonWithTitle:@"Nah that's okay"];
[alert show];
And that’s it. No delegate stuff to worry about, no other methods to implement.
Feel free to use this in your own code. Attribution to me and mention of this blog would be nice if you do.