PageRenderTime 43ms CodeModel.GetById 14ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

/BlocksKit/UIAlertView+BlocksKit.m

http://github.com/zwaldowski/BlocksKit
Objective C | 214 lines | 155 code | 50 blank | 9 comment | 32 complexity | 04f86a0975456e0a77133e7d0497714c MD5 | raw file
  1//
  2//  UIAlertView+BlocksKit.m
  3//  BlocksKit
  4//
  5
  6#import "NSArray+BlocksKit.h"
  7#import "UIAlertView+BlocksKit.h"
  8#import "A2BlockDelegate+BlocksKit.h"
  9
 10#pragma mark Delegate
 11
 12@interface A2DynamicUIAlertViewDelegate : A2DynamicDelegate <UIAlertViewDelegate>
 13
 14@end
 15
 16@implementation A2DynamicUIAlertViewDelegate
 17
 18- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView {
 19	BOOL should = YES;
 20	
 21	id realDelegate = self.realDelegate;
 22	if (realDelegate && [realDelegate respondsToSelector:@selector(alertViewShouldEnableFirstOtherButton:)])
 23		should &= [realDelegate alertViewShouldEnableFirstOtherButton:alertView];
 24	
 25	BOOL (^block)(UIAlertView *) = [self blockImplementationForMethod:_cmd];
 26	if (block)
 27		should &= block(alertView);
 28	
 29	return should;
 30}
 31
 32- (void)alertViewCancel:(UIAlertView *)alertView {
 33	id realDelegate = self.realDelegate;
 34	if (realDelegate && [realDelegate respondsToSelector:@selector(alertViewCancel:)])
 35		[realDelegate alertViewCancel:alertView];
 36	
 37	id key = [NSNumber numberWithInteger:alertView.cancelButtonIndex];
 38	BKBlock cancelBlock = [self.handlers objectForKey:key];
 39	if (cancelBlock)
 40		cancelBlock();
 41}
 42
 43- (void)willPresentAlertView:(UIAlertView *)alertView {
 44	id realDelegate = self.realDelegate;
 45	if (realDelegate && [realDelegate respondsToSelector:@selector(willPresentAlertView:)])
 46		[realDelegate willPresentAlertView:alertView];
 47	
 48	void (^block)(UIAlertView *) = [self blockImplementationForMethod:_cmd];
 49	if (block)
 50		block(alertView);
 51}
 52
 53- (void)didPresentAlertView:(UIAlertView *)alertView {
 54	id realDelegate = self.realDelegate;
 55	if (realDelegate && [realDelegate respondsToSelector:@selector(didPresentAlertView:)])
 56		[realDelegate didPresentAlertView:alertView];
 57	
 58	void (^block)(UIAlertView *) = [self blockImplementationForMethod:_cmd];
 59	if (block)
 60		block(alertView);
 61}
 62
 63- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
 64	id realDelegate = self.realDelegate;
 65	if (realDelegate && [realDelegate respondsToSelector:@selector(alertView:willDismissWithButtonIndex:)])
 66		[realDelegate alertView:alertView willDismissWithButtonIndex:buttonIndex];
 67	
 68	void (^block)(UIAlertView *, NSInteger) = [self blockImplementationForMethod:_cmd];
 69	if (block)
 70		block(alertView, buttonIndex);
 71}
 72
 73- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
 74	id realDelegate = self.realDelegate;
 75	if (realDelegate && [realDelegate respondsToSelector:@selector(alertView:didDismissWithButtonIndex:)])
 76		[realDelegate alertView:alertView didDismissWithButtonIndex:buttonIndex];
 77	
 78	void (^block)(UIAlertView *, NSInteger) = [self blockImplementationForMethod:_cmd];
 79	if (block)
 80		block(alertView, buttonIndex);
 81}
 82
 83- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
 84	id realDelegate = self.realDelegate;
 85	if (realDelegate && [realDelegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)])
 86		[realDelegate alertView:alertView clickedButtonAtIndex:buttonIndex];
 87	
 88	void (^block)(UIAlertView *, NSInteger) = [self blockImplementationForMethod:_cmd];
 89	if (block)
 90		block(alertView, buttonIndex);
 91	
 92	id key = [NSNumber numberWithInteger:buttonIndex];
 93	BKBlock buttonBlock = [self.handlers objectForKey: key];
 94	if (buttonBlock)
 95		buttonBlock();
 96}
 97
 98@end
 99
100#pragma mark - Category
101
102@implementation UIAlertView (BlocksKit)
103
104@dynamic willShowBlock, didShowBlock, willDismissBlock, didDismissBlock, shouldEnableFirstOtherButtonBlock;
105
106+ (void)load {
107	@autoreleasepool {
108		[self registerDynamicDelegate];
109		NSDictionary *methods = [NSDictionary dictionaryWithObjectsAndKeys:
110								 @"willPresentAlertView:", @"willShowBlock",
111								 @"didPresentAlertView:", @"didShowBlock",
112								 @"alertView:willDismissWithButtonIndex:", @"willDismissBlock",
113								 @"alertView:didDismissWithButtonIndex:", @"didDismissBlock",
114								 @"alertViewShouldEnableFirstOtherButton:", @"shouldEnableFirstOtherButtonBlock",
115								 nil];
116		[self linkDelegateMethods:methods];
117	}
118}
119
120#pragma mark Convenience
121
122+ (void) showAlertViewWithTitle: (NSString *) title message: (NSString *) message cancelButtonTitle: (NSString *) cancelButtonTitle otherButtonTitles: (NSArray *) otherButtonTitles handler: (void (^)(UIAlertView *, NSInteger)) block
123{
124	UIAlertView *alertView = [UIAlertView alertViewWithTitle: title message: message];
125	
126	// If no buttons were specified, cancel button becomes "Dismiss"
127	if (!cancelButtonTitle.length && !otherButtonTitles.count)
128		cancelButtonTitle = NSLocalizedString(@"Dismiss", nil);
129	
130	// Set cancel button
131	if (cancelButtonTitle.length)
132		alertView.cancelButtonIndex = [alertView addButtonWithTitle: cancelButtonTitle];
133	
134	// Set other buttons
135	if (otherButtonTitles.count)
136	{
137		NSUInteger firstOtherButton = [alertView addButtonWithTitle: [otherButtonTitles objectAtIndex: 0]];
138		[alertView setValue: [NSNumber numberWithInteger: firstOtherButton] forKey: @"firstOtherButton"];
139		
140		otherButtonTitles = [otherButtonTitles subarrayWithRange: NSMakeRange(1, otherButtonTitles.count - 1)];
141		[otherButtonTitles each: ^(NSString *button) {
142			[alertView addButtonWithTitle: button];
143		}];
144	}
145	
146	// Set `didDismissBlock`
147	if (block) alertView.didDismissBlock = block;
148	
149	// Show alert view
150	[alertView show];
151}
152
153#pragma mark Initializers
154
155+ (id)alertViewWithTitle:(NSString *)title {
156	return [self alertViewWithTitle:title message:nil];
157}
158
159+ (id)alertViewWithTitle:(NSString *)title message:(NSString *)message {
160	return [[[UIAlertView alloc] initWithTitle:title message:message] autorelease];
161}
162
163- (id)initWithTitle:(NSString *)title message:(NSString *)message {
164	return [self initWithTitle:title message:message delegate:self.dynamicDelegate cancelButtonTitle:nil otherButtonTitles:nil];
165}
166
167#pragma Actions
168
169- (NSInteger)addButtonWithTitle:(NSString *)title handler:(BKBlock)block {
170	NSAssert(title.length, @"A button without a title cannot be added to the alert view.");
171	NSInteger index = [self addButtonWithTitle:title];
172	[self setHandler:block forButtonAtIndex:index];
173	return index;
174}
175
176- (NSInteger)setCancelButtonWithTitle:(NSString *)title handler:(BKBlock)block {
177	if (!title.length)
178		title = NSLocalizedString(@"Cancel", nil);
179	NSInteger cancelButtonIndex = [self addButtonWithTitle:title];
180	self.cancelButtonIndex = cancelButtonIndex;
181	[self setHandler:block forButtonAtIndex:cancelButtonIndex];
182	return cancelButtonIndex;
183}
184
185#pragma mark Properties
186
187- (void)setHandler:(BKBlock)block forButtonAtIndex:(NSInteger)index {
188	id key = [NSNumber numberWithInteger:index];
189	
190	if (block)
191		[[self.dynamicDelegate handlers] setObject:block forKey:key];
192	else
193		[[self.dynamicDelegate handlers] removeObjectForKey:key];
194}
195
196- (BKBlock)handlerForButtonAtIndex:(NSInteger)index {
197	id key = [NSNumber numberWithInteger:index];
198	return [[self.dynamicDelegate handlers] objectForKey:key];
199}
200
201- (BKBlock)cancelBlock {
202	return [self handlerForButtonAtIndex:self.cancelButtonIndex];
203}
204
205- (void)setCancelBlock:(BKBlock)block {
206	if (block && self.cancelButtonIndex == -1) {
207		[self setCancelButtonWithTitle:nil handler:block];
208		return;
209	}
210	
211	[self setHandler:block forButtonAtIndex:self.cancelButtonIndex];
212}
213
214@end