Created
August 14, 2013 08:56
-
-
Save lukeredpath/6229171 to your computer and use it in GitHub Desktop.
I wanted a block-based API for UIAlertView on my current project, but didn't want to import a whole Pod/library just for that, so I wrote a quick and simple implementation myself. Licensed under the WTFPL license. (http://www.wtfpl.net).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UIAlertView+BlockSupport.h | |
// | |
// Created by Luke Redpath on 08/08/2013. | |
// | |
#import <UIKit/UIKit.h> | |
/* Called when the user taps a button in the alert view or the alert | |
* is cancelled. | |
* | |
* If the alert was cancelled, wasCancelled will be YES and tappedButtonIndex | |
* will return the value of [UIAlertView cancelButtonIndex]. | |
*/ | |
typedef void (^LRAlertViewCompletionHandler)(UIAlertView *alertView, NSInteger tappedButtonIndex, BOOL wasCancelled); | |
@interface UIAlertView (BlockSupport) | |
- (void)showWithCompletionHandler:(LRAlertViewCompletionHandler)completionHandler; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UIAlertView+BlockSupport.m | |
// | |
// Created by Luke Redpath on 08/08/2013. | |
// Copyright (c) 2013 Luke Redpath. All rights reserved. | |
// | |
#import "UIAlertView+BlockSupport.h" | |
#import <objc/runtime.h> | |
@interface LRAlertViewBlockDelegate : NSObject <UIAlertViewDelegate> | |
- (id)initWithAlertView:(UIAlertView *)alertView; | |
- (void)showWithCompletionHandler:(LRAlertViewCompletionHandler)completionHandler; | |
@end | |
#pragma mark - | |
@implementation UIAlertView (BlockSupport) | |
- (void)showWithCompletionHandler:(LRAlertViewCompletionHandler)completionHandler | |
{ | |
NSParameterAssert(completionHandler); | |
CNAlertViewBlockDelegate *blockDelegate = [[LRAlertViewBlockDelegate alloc] initWithAlertView:self]; | |
[blockDelegate showWithCompletionHandler:completionHandler]; | |
} | |
@end | |
#pragma mark - | |
@implementation LRAlertViewBlockDelegate { | |
UIAlertView *_alertView; | |
LRAlertViewCompletionHandler _completionHandler; | |
} | |
#define kLRAlertViewBlockDelegateRefKey "LRAlertViewBlockDelegate" | |
- (id)initWithAlertView:(UIAlertView *)alertView | |
{ | |
if ((self = [super init])) { | |
_alertView = alertView; | |
_alertView.delegate = self; | |
} | |
return self; | |
} | |
- (void)showWithCompletionHandler:(LRAlertViewCompletionHandler)completionHandler | |
{ | |
_completionHandler = [completionHandler copy]; | |
/* We need to keep a strong reference to self or it will just be deallocated immediately. | |
* | |
* This technically creates a retain cycle between the alert view and self which is OK, | |
* as we will make sure we break this retain cycle manually when the alert view is dismissed. | |
*/ | |
objc_setAssociatedObject(_alertView, kLRAlertViewBlockDelegateRefKey, self, OBJC_ASSOCIATION_RETAIN); | |
[_alertView show]; | |
} | |
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex | |
{ | |
_completionHandler(alertView, buttonIndex, NO); | |
} | |
- (void)alertViewCancel:(UIAlertView *)alertView | |
{ | |
_completionHandler(alertView, alertView.cancelButtonIndex, YES); | |
} | |
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex | |
{ | |
/* The alert view will be deallocced shortly after this is called if nothing else is retaining | |
* it, so now's a good time to break the retain cycle. | |
*/ | |
objc_setAssociatedObject(_alertView, kLRAlertViewBlockDelegateRefKey, nil, OBJC_ASSOCIATION_RETAIN); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment