You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.9 KiB
208 lines
5.9 KiB
//
|
|
// FLEXAlert.m
|
|
// FLEX
|
|
//
|
|
// Created by Tanner Bennett on 8/20/19.
|
|
// Copyright © 2019 Flipboard. All rights reserved.
|
|
//
|
|
|
|
#import "FLEXAlert.h"
|
|
|
|
@interface FLEXAlert ()
|
|
@property (nonatomic, readonly) UIAlertController *_controller;
|
|
@property (nonatomic, readonly) NSMutableArray<FLEXAlertAction *> *_actions;
|
|
@end
|
|
|
|
#define FLEXAlertActionMutationAssertion() \
|
|
NSAssert(!self._action, @"Cannot mutate action after retreiving underlying UIAlertAction");
|
|
|
|
@interface FLEXAlertAction ()
|
|
@property (nonatomic) UIAlertController *_controller;
|
|
@property (nonatomic) NSString *_title;
|
|
@property (nonatomic) UIAlertActionStyle _style;
|
|
@property (nonatomic) BOOL _disable;
|
|
@property (nonatomic) void(^_handler)(UIAlertAction *action);
|
|
@property (nonatomic) UIAlertAction *_action;
|
|
@end
|
|
|
|
@implementation FLEXAlert
|
|
|
|
+ (void)showAlert:(NSString *)title message:(NSString *)message from:(UIViewController *)viewController {
|
|
[self makeAlert:^(FLEXAlert *make) {
|
|
make.title(title).message(message).button(@"Dismiss").cancelStyle();
|
|
} showFrom:viewController];
|
|
}
|
|
|
|
#pragma mark Initialization
|
|
|
|
- (instancetype)initWithController:(UIAlertController *)controller {
|
|
self = [super init];
|
|
if (self) {
|
|
__controller = controller;
|
|
__actions = [NSMutableArray new];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
+ (UIAlertController *)make:(FLEXAlertBuilder)block withStyle:(UIAlertControllerStyle)style {
|
|
// Create alert builder
|
|
FLEXAlert *alert = [[self alloc] initWithController:
|
|
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:style]
|
|
];
|
|
|
|
// Configure alert
|
|
block(alert);
|
|
|
|
// Add actions
|
|
for (FLEXAlertAction *builder in alert._actions) {
|
|
[alert._controller addAction:builder.action];
|
|
}
|
|
|
|
return alert._controller;
|
|
}
|
|
|
|
+ (void)make:(FLEXAlertBuilder)block withStyle:(UIAlertControllerStyle)style showFrom:(UIViewController *)viewController {
|
|
UIAlertController *alert = [self make:block withStyle:style];
|
|
[viewController presentViewController:alert animated:YES completion:nil];
|
|
}
|
|
|
|
+ (void)makeAlert:(FLEXAlertBuilder)block showFrom:(UIViewController *)viewController {
|
|
[self make:block withStyle:UIAlertControllerStyleAlert showFrom:viewController];
|
|
}
|
|
|
|
+ (void)makeSheet:(FLEXAlertBuilder)block showFrom:(UIViewController *)viewController {
|
|
[self make:block withStyle:UIAlertControllerStyleActionSheet showFrom:viewController];
|
|
}
|
|
|
|
+ (UIAlertController *)makeAlert:(FLEXAlertBuilder)block {
|
|
return [self make:block withStyle:UIAlertControllerStyleAlert];
|
|
}
|
|
|
|
+ (UIAlertController *)makeSheet:(FLEXAlertBuilder)block {
|
|
return [self make:block withStyle:UIAlertControllerStyleActionSheet];
|
|
}
|
|
|
|
#pragma mark Configuration
|
|
|
|
- (FLEXAlertStringProperty)title {
|
|
return ^FLEXAlert *(NSString *title) {
|
|
if (self._controller.title) {
|
|
self._controller.title = [self._controller.title stringByAppendingString:title];
|
|
} else {
|
|
self._controller.title = title;
|
|
}
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertStringProperty)message {
|
|
return ^FLEXAlert *(NSString *message) {
|
|
if (self._controller.message) {
|
|
self._controller.message = [self._controller.message stringByAppendingString:message];
|
|
} else {
|
|
self._controller.message = message;
|
|
}
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertAddAction)button {
|
|
return ^FLEXAlertAction *(NSString *title) {
|
|
FLEXAlertAction *action = FLEXAlertAction.new.title(title);
|
|
action._controller = self._controller;
|
|
[self._actions addObject:action];
|
|
return action;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertStringArg)textField {
|
|
return ^FLEXAlert *(NSString *placeholder) {
|
|
[self._controller addTextFieldWithConfigurationHandler:^(UITextField *textField) {
|
|
textField.placeholder = placeholder;
|
|
}];
|
|
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertTextField)configuredTextField {
|
|
return ^FLEXAlert *(void(^configurationHandler)(UITextField *)) {
|
|
[self._controller addTextFieldWithConfigurationHandler:configurationHandler];
|
|
return self;
|
|
};
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation FLEXAlertAction
|
|
|
|
- (FLEXAlertActionStringProperty)title {
|
|
return ^FLEXAlertAction *(NSString *title) {
|
|
FLEXAlertActionMutationAssertion();
|
|
if (self._title) {
|
|
self._title = [self._title stringByAppendingString:title];
|
|
} else {
|
|
self._title = title;
|
|
}
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertActionProperty)destructiveStyle {
|
|
return ^FLEXAlertAction *() {
|
|
FLEXAlertActionMutationAssertion();
|
|
self._style = UIAlertActionStyleDestructive;
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertActionProperty)cancelStyle {
|
|
return ^FLEXAlertAction *() {
|
|
FLEXAlertActionMutationAssertion();
|
|
self._style = UIAlertActionStyleCancel;
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertActionBOOLProperty)enabled {
|
|
return ^FLEXAlertAction *(BOOL enabled) {
|
|
FLEXAlertActionMutationAssertion();
|
|
self._disable = !enabled;
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (FLEXAlertActionHandler)handler {
|
|
return ^FLEXAlertAction *(void(^handler)(NSArray<NSString *> *)) {
|
|
FLEXAlertActionMutationAssertion();
|
|
|
|
// Get weak reference to the alert to avoid block <--> alert retain cycle
|
|
__weak __typeof(self._controller) weakController = self._controller;
|
|
self._handler = ^(UIAlertAction *action) {
|
|
// Strongify that reference and pass the text field strings to the handler
|
|
__strong __typeof(weakController) controller = weakController;
|
|
NSArray *strings = [controller.textFields valueForKeyPath:@"text"];
|
|
handler(strings);
|
|
};
|
|
|
|
return self;
|
|
};
|
|
}
|
|
|
|
- (UIAlertAction *)action {
|
|
if (self._action) {
|
|
return self._action;
|
|
}
|
|
|
|
self._action = [UIAlertAction
|
|
actionWithTitle:self._title
|
|
style:self._style
|
|
handler:self._handler
|
|
];
|
|
self._action.enabled = !self._disable;
|
|
|
|
return self._action;
|
|
}
|
|
|
|
@end
|