Created
September 2, 2014 13:52
-
-
Save mbbischoff/50c9e0fa06a4795a3812 to your computer and use it in GitHub Desktop.
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
// | |
// LCKAlertPresenter.h | |
// Quotebook | |
// | |
// Created by Matthew Bischoff on 9/1/14. | |
// Copyright (c) 2014 Lickability. All rights reserved. | |
// | |
@import Foundation; | |
@protocol LCKActionSheetPopoverPresenting <NSObject> | |
@property (nonatomic) UIView *sourceView; | |
@property (nonatomic) CGRect sourceRect; | |
@property (nonatomic) UIBarButtonItem *barButtonItem; | |
@end | |
@protocol LCKActionSheetActing <NSObject> | |
+ (instancetype)actionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(id <LCKActionSheetActing> action))handler; | |
@property (nonatomic, copy) void (^handler)(id <LCKActionSheetActing> action); | |
@property (nonatomic, readonly) NSString *title; | |
@property (nonatomic, readonly) UIAlertActionStyle style; | |
@end | |
@interface LCKActionSheetAction : NSObject <LCKActionSheetActing> | |
@end | |
/** | |
* LCKActionSheetPresenter is a facade for UIActionSheet and UIAlertController that adapts depending on availability. | |
*/ | |
@interface LCKActionSheetPresenter : NSObject | |
+ (instancetype)alertPresenterWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle; | |
- (void)addAction:(LCKActionSheetAction *)action; | |
- (void)presentInViewController:(UIViewController *)viewController view:(UIView *)view animated:(BOOL)animated; | |
@property (nonatomic, readonly) NSArray *actions; | |
@property (nonatomic, copy) NSString *title; | |
/// LCKActionSheetPopoverPresenter or UIPopoverPresentationController | |
@property (nonatomic, readonly) id <LCKActionSheetPopoverPresenting> popoverPresentationController; | |
@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
// | |
// LCKAlertPresenter.m | |
// Quotebook | |
// | |
// Created by Matthew Bischoff on 9/1/14. | |
// Copyright (c) 2014 Lickability. All rights reserved. | |
// | |
#import "LCKActionSheetPresenter.h" | |
#import "LCKAlertController.h" | |
#import "LCKActionSheet.h" | |
@interface LCKActionSheetPopoverPresenter : NSObject <LCKActionSheetPopoverPresenting> | |
@end | |
@implementation LCKActionSheetPopoverPresenter | |
@synthesize sourceView = _sourceView; | |
@synthesize sourceRect = _sourceRect; | |
@synthesize barButtonItem = _barButtonItem; | |
@end | |
@interface LCKActionSheetAction () | |
@property (nonatomic, readwrite) NSString *title; | |
@property (nonatomic) UIAlertActionStyle style; | |
@end | |
@implementation LCKActionSheetAction | |
@synthesize handler = _handler; | |
@synthesize title = _title; | |
@synthesize style = _style; | |
+ (instancetype)actionWithTitle:(NSString *)title style:(UIAlertActionStyle)style handler:(void (^)(id <LCKActionSheetActing> action))handler { | |
LCKActionSheetAction *action = [[LCKActionSheetAction alloc] init]; | |
action.title = title; | |
action.style = style; | |
action.handler = [handler copy]; | |
return action; | |
} | |
- (UIAlertAction *)UIAlertAction { | |
return [UIAlertAction actionWithTitle:self.title style:self.style handler:(void(^)(UIAlertAction *))self.handler]; | |
} | |
@end | |
@interface LCKActionSheetPresenter () <UIActionSheetDelegate> | |
@property (nonatomic) NSArray *actions; | |
@property (nonatomic) UIAlertController *alertController; | |
@property (nonatomic) id <LCKActionSheetPopoverPresenting> popoverPresentationController; | |
@end | |
@implementation LCKActionSheetPresenter | |
+ (instancetype)alertPresenterWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle { | |
return [[LCKActionSheetPresenter alloc] initWithTitle:title message:nil preferredStyle:preferredStyle]; | |
} | |
- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle { | |
self = [super init]; | |
if (self) { | |
_title = [title copy]; | |
_actions = @[]; | |
if ([UIAlertController class]) { | |
_alertController = [LCKAlertController alertControllerWithTitle:self.title message:nil preferredStyle:UIAlertControllerStyleActionSheet]; | |
} | |
} | |
return self; | |
} | |
- (void)addAction:(LCKActionSheetAction *)action { | |
if (action) { | |
self.actions = [self.actions arrayByAddingObjectsFromArray:@[action]]; | |
} | |
if ([UIAlertAction class]) { | |
[self.alertController addAction:[action UIAlertAction]]; | |
} | |
} | |
- (UIActionSheet *)newActionSheet { | |
LCKActionSheet *actionSheet = [[LCKActionSheet alloc] initWithTitle:self.title delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil]; | |
__block NSInteger cancelIndex = -1; | |
__block NSInteger destructiveIndex = NSNotFound; | |
__block LCKActionSheetAction *cancelAction; | |
[self.actions enumerateObjectsUsingBlock:^(LCKActionSheetAction *action, NSUInteger actionIndex, BOOL *stop) { | |
if (action.style == UIAlertActionStyleCancel) { | |
cancelAction = action; | |
cancelIndex = actionIndex; | |
} | |
else { | |
[actionSheet addButtonWithTitle:action.title]; | |
} | |
if (action.style == UIAlertActionStyleDestructive) { | |
destructiveIndex = actionIndex; | |
} | |
}]; | |
if (cancelAction) { | |
actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:cancelAction.title]; | |
} | |
actionSheet.destructiveButtonIndex = destructiveIndex; | |
return actionSheet; | |
} | |
- (void)presentInViewController:(UIViewController *)viewController view:(UIView *)view animated:(BOOL)animated { | |
if ([UIAlertController class]) { | |
[viewController presentViewController:self.alertController animated:animated completion:nil]; | |
} | |
else { | |
UIActionSheet *actionSheet = [self newActionSheet]; | |
if (self.popoverPresentationController.barButtonItem) { | |
[actionSheet showFromBarButtonItem:self.popoverPresentationController.barButtonItem animated:animated]; | |
} | |
else if (self.popoverPresentationController.sourceView) { | |
[actionSheet showFromRect:self.popoverPresentationController.sourceRect inView:self.popoverPresentationController.sourceView animated:animated]; | |
} | |
else { | |
[actionSheet showInView:view]; | |
} | |
} | |
} | |
- (NSArray *)actionsAsUIAlertActions { | |
NSMutableArray *UIAlertActions = [NSMutableArray array]; | |
for (LCKActionSheetAction *action in self.actions) { | |
[UIAlertActions addObject:[action UIAlertAction]]; | |
} | |
return UIAlertActions; | |
} | |
- (id)popoverPresentationController { | |
if ([self.alertController respondsToSelector:@selector(popoverPresentationController)]) { | |
return self.alertController.popoverPresentationController; | |
} | |
else if (!_popoverPresentationController) { | |
_popoverPresentationController = [[LCKActionSheetPopoverPresenter alloc] init]; | |
} | |
return _popoverPresentationController; | |
} | |
#pragma mark - UIActionSheetDelegate | |
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { | |
actionSheet.delegate = nil; | |
NSMutableArray *correctedActions = [self.actions mutableCopy]; | |
LCKActionSheetAction *cancelAction; | |
for (LCKActionSheetAction *action in self.actions) { | |
if (action.style == UIAlertActionStyleCancel) { | |
cancelAction = action; | |
} | |
} | |
if (cancelAction) { | |
[correctedActions removeObject:cancelAction]; | |
[correctedActions addObject:cancelAction]; | |
} | |
LCKActionSheetAction *action = correctedActions[buttonIndex]; | |
if (action.handler) { | |
action.handler(action); | |
} | |
} | |
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { | |
actionSheet.delegate = nil; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment