808 lines
30 KiB
Objective-C
808 lines
30 KiB
Objective-C
//
|
||
// MTAlertView.m
|
||
// Meet
|
||
//
|
||
// Created by ko1o on 2018/9/17.
|
||
// Copyright © 2018年 ko1o. All rights reserved.
|
||
//
|
||
|
||
#import "MTAlertView.h"
|
||
#import "zhPopupController.h"
|
||
#import "UIImageView+WebCache.h"
|
||
#import "IQKeyboardManager.h"
|
||
|
||
#define kMTAlertViewLineColor [UIColor colorWithRed:0xbf/ 255.0 green:0xbf/ 255.0 blue:0xbf/ 255.0 alpha:1]
|
||
#define kMTAlertIconDefaultWidth MTAlertFixSize(60)
|
||
#define kMTAlertBottomCancelButtonWidth MTAlertFixSize(38)
|
||
#define KMTAlertBottomCancelTopMargin MTAlertFixSize(40)
|
||
|
||
#ifndef COLOR_WITH_RGB
|
||
#define COLOR_WITH_RGB RGB_HEX
|
||
#endif
|
||
#ifndef COLOR_WITH_RGB_A
|
||
#define COLOR_WITH_RGB_A(hex, a) [UIColor colorWithRed:((hex & 0x00FF0000) >> 16)/255.0f green:((hex & 0x0000FF00) >> 8)/255.0f blue:(hex & 0x000000FF)/255.0f alpha:(a)]
|
||
#endif
|
||
|
||
|
||
static NSMutableArray *gShowingAlterViews;
|
||
static NSMutableArray *gShowingPopupWindows;
|
||
|
||
@interface MTAlertButton ()
|
||
|
||
@property (nonatomic, strong) CALayer *horizontalLine;
|
||
@property (nonatomic, strong) CALayer *verticalLine;
|
||
@property (nonatomic, copy) MTAlertButtonHandler buttonClickedBlock;
|
||
@end
|
||
|
||
@implementation MTAlertButton
|
||
|
||
+ (instancetype)buttonWithType:(MTAlertButtonType)type title:(NSString *)title handler:(MTAlertButtonHandler)handler {
|
||
return [[self alloc] initWithType:type title:title handler:handler];
|
||
}
|
||
|
||
- (instancetype)initWithType:(MTAlertButtonType)type title:(NSString *)title handler:(MTAlertButtonHandler)handler {
|
||
if (self = [super init]) {
|
||
self.buttonClickedBlock = handler;
|
||
|
||
self.titleLabel.font = MT_FONT_REGULAR_SIZE(13.0);
|
||
self.height = FIX_SIZE(40);
|
||
UIColor *normalColor = COLOR_WITH_RGB(0x000000);
|
||
UIColor *highlightedColor = COLOR_WITH_RGB_A(0x000000, 0.5);
|
||
switch (type) {
|
||
case MTAlertButtonTypeDefault:
|
||
case MTAlertButtonTypeDefaultDestructive:
|
||
case MTAlertButtonTypeDefaultTheme:
|
||
{
|
||
if (type == MTAlertButtonTypeDefaultTheme) {
|
||
normalColor = COLOR_WITH_RGB(0x040000);
|
||
self.backgroundColor = THEME_COLOR;
|
||
// highlightedColor = THEME_COLOR;
|
||
} else if (type == MTAlertButtonTypeDefaultDestructive) {
|
||
normalColor = [UIColor whiteColor];
|
||
self.backgroundColor = COLOR_WITH_RGB(0xFF5571);
|
||
// highlightedColor = COLOR_WITH_RGB_A(0xFF5571, 0.5);
|
||
} else {
|
||
normalColor = COLOR_WITH_RGB(0xB3B3B3);
|
||
self.backgroundColor = COLOR_WITH_RGB_A(0xFFFFFF, 0.1);
|
||
}
|
||
[self setTitleColor:normalColor forState:UIControlStateNormal];
|
||
// [self setTitleColor:highlightedColor forState:UIControlStateHighlighted];
|
||
self.layer.cornerRadius = FIX_SIZE(16);
|
||
self.clipsToBounds = YES;
|
||
// _horizontalLine = [CALayer layer];
|
||
// _horizontalLine.backgroundColor = kMTAlertViewLineColor.CGColor;
|
||
// [self.layer addSublayer:_horizontalLine];
|
||
// _horizontalLine.hidden = YES;
|
||
//
|
||
// _verticalLine = [CALayer layer];
|
||
// _verticalLine.backgroundColor = kMTAlertViewLineColor.CGColor;
|
||
// [self.layer addSublayer:_verticalLine];
|
||
// _verticalLine.hidden = YES;
|
||
break;
|
||
}
|
||
case MTAlertButtonTypeNormal:
|
||
{
|
||
[self setTitleColor:COLOR_WITH_RGB(0x040000) forState:UIControlStateNormal];
|
||
self.backgroundColor = THEME_COLOR;
|
||
break;
|
||
}
|
||
case MTAlertButtonTypeCancel:
|
||
{
|
||
[self setTitleColor:COLOR_WITH_RGB(0x737373) forState:UIControlStateNormal];
|
||
self.backgroundColor = COLOR_WITH_RGB(0xFFFFFF);
|
||
break;
|
||
}
|
||
case MTAlertButtonTypeDestructive:
|
||
{
|
||
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||
[self setTitleColor:COLOR_WITH_RGB(0xcccccc) forState:UIControlStateHighlighted];
|
||
self.backgroundColor = COLOR_WITH_RGB(0xFF5571);
|
||
break;
|
||
}
|
||
|
||
default:
|
||
break;
|
||
}
|
||
// self.layer.cornerRadius = FIX_SIZE(3);
|
||
|
||
self.titleLabel.adjustsFontSizeToFitWidth = YES;
|
||
[self setTitle:title forState:UIControlStateNormal];
|
||
[self addTarget:self action:@selector(handlerClicked) forControlEvents:UIControlEventTouchUpInside];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (void)handlerClicked {
|
||
|
||
if (self && self.buttonClickedBlock) self.buttonClickedBlock(self);
|
||
}
|
||
|
||
- (void)layoutSubviews {
|
||
[super layoutSubviews];
|
||
CGFloat lineWidth = self.lineWidth > 0 ? self.lineWidth : 1 / [UIScreen mainScreen].scale;
|
||
_horizontalLine.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), lineWidth);
|
||
_verticalLine.frame = CGRectMake(0, 0, lineWidth, CGRectGetHeight(self.frame));
|
||
|
||
_horizontalLine.hidden = _verticalLine.hidden = self.buttonType == MTAlertButtonTypeDefault ||
|
||
self.buttonType == MTAlertButtonTypeDefaultDestructive ||
|
||
self.buttonType == MTAlertButtonTypeDefaultTheme;
|
||
}
|
||
|
||
- (void)setLineColor:(UIColor *)lineColor {
|
||
_lineColor = lineColor;
|
||
_verticalLine.backgroundColor = lineColor.CGColor;
|
||
_horizontalLine.backgroundColor = lineColor.CGColor;
|
||
}
|
||
|
||
@end
|
||
|
||
@interface MTAlertView () {
|
||
CGFloat _paddingTop, _paddingBottom, _paddingLeft; // paddingRight = paddingLeft
|
||
CGFloat _spacing;
|
||
|
||
UIEdgeInsets _bottomCancelButtonInsets;
|
||
|
||
UIFont * _messageLabelFont;
|
||
UIFont * _titleLabelFont;
|
||
zhPopupController *_popupController;
|
||
}
|
||
@property (nonatomic, strong) UIView *containerView;
|
||
|
||
@property (nonatomic, strong, readonly) UIButton *bottomCancelButton;
|
||
@property (nonatomic, strong, readonly) UIImageView *iconImageView;
|
||
|
||
@property (nonatomic, strong, readonly) UILabel *titleLabel;
|
||
@property (nonatomic, assign) CGFloat subOverflyButtonHeight;/// 子视图按钮的高度,默认40
|
||
@property (nonatomic, assign) CGFloat subOverflyButtonLeftRightMargin;/// 子视图按钮左右边距 默认 16
|
||
@property (nonatomic, assign) CGFloat subOverflyButtonMargin;/// 子视图按钮之间的间距 默认 10
|
||
|
||
@property (nonatomic, strong) NSMutableSet *subActions;
|
||
@property (nonatomic, strong) NSMutableSet *adjoinActions;
|
||
@property (nonatomic, assign) CGSize contentSize;
|
||
|
||
@property (nonatomic, strong) UIView *customTopView;
|
||
@property (nonatomic, strong) UIView *alertButtonContentView;
|
||
|
||
@property (nonatomic, assign) BOOL shouldBottomCancelButton;
|
||
|
||
/// 纵向依次向下添加
|
||
- (void)addAction:(nonnull MTAlertButton *)action;
|
||
|
||
/// 水平方向两个button
|
||
- (void)adjoinWithLeftAction:(MTAlertButton *)leftAction rightAction:(MTAlertButton *)rightAction;
|
||
|
||
@end
|
||
|
||
@interface MTAlertViewConfig ()
|
||
|
||
@property (nonatomic, assign) MTAlertButtonType cancelButtonType;
|
||
|
||
@end
|
||
|
||
@implementation MTAlertViewConfig
|
||
|
||
- (instancetype)init
|
||
{
|
||
if (self = [super init]) {
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (void)setOtherDestructiveTitle:(NSString *)otherDestructiveTitle
|
||
{
|
||
_otherDestructiveTitle = otherDestructiveTitle;
|
||
|
||
_otherTitle = otherDestructiveTitle;
|
||
self.otherButtonType = MTAlertButtonTypeDefaultDestructive;
|
||
}
|
||
|
||
- (void)setOtherDefaultDestructiveTitle:(NSString *)otherDefaultDestructiveTitle
|
||
{
|
||
_otherDefaultDestructiveTitle = otherDefaultDestructiveTitle;
|
||
|
||
_otherTitle = otherDefaultDestructiveTitle;
|
||
self.otherButtonType = MTAlertButtonTypeDefaultDestructive;
|
||
}
|
||
|
||
- (void)setOtherButtonType:(MTAlertButtonType)otherButtonType
|
||
{
|
||
_otherButtonType = otherButtonType;
|
||
|
||
switch (otherButtonType) {
|
||
case MTAlertButtonTypeNormal:
|
||
case MTAlertButtonTypeDestructive:
|
||
_cancelButtonType = MTAlertButtonTypeCancel;
|
||
break;
|
||
case MTAlertButtonTypeDefaultDestructive:
|
||
case MTAlertButtonTypeDefault:
|
||
_cancelButtonType = MTAlertButtonTypeDefault;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
@end
|
||
|
||
@implementation MTAlertView
|
||
|
||
static void *SnailAlertViewActionKey = &SnailAlertViewActionKey;
|
||
|
||
- (void)setAlpha:(CGFloat)alpha
|
||
{
|
||
[super setAlpha:alpha];
|
||
|
||
self.config.popupController.alpha = alpha;
|
||
}
|
||
|
||
- (instancetype)initWithSetupBlock:(MTAlertViewSetupBlock)setupBlock
|
||
{
|
||
MTAlertViewConfig *config = [[MTAlertViewConfig alloc] init];
|
||
config.otherButtonType = MTAlertButtonTypeDefaultTheme;
|
||
|
||
if (setupBlock) {
|
||
setupBlock(config);
|
||
}
|
||
if (self = [super init]) {
|
||
_config = config;
|
||
[self setupUIWithConfig:config];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
+ (instancetype)alertViewWithSetupBlock:(MTAlertViewSetupBlock)setupBlock
|
||
{
|
||
return [[MTAlertView alloc] initWithSetupBlock:setupBlock];
|
||
}
|
||
|
||
+ (MTAlertView *)showWithSetupBlcok:(MTAlertViewSetupBlock)setupBlock
|
||
{
|
||
MTAlertView *alrtView = [self alertViewWithSetupBlock:setupBlock];
|
||
return [alrtView show];
|
||
}
|
||
|
||
- (void)setupUIWithConfig:(MTAlertViewConfig *)config
|
||
{
|
||
// 默认初始化
|
||
[self defaultSetup];
|
||
|
||
if (config.customView) {
|
||
[self setupCustomAlertWithConfig:config];
|
||
return;
|
||
}
|
||
|
||
if (config.icon || config.cancelButtonType == MTAlertButtonTypeCancel) {
|
||
[self setupIconAlertWithConfig:config];
|
||
return;
|
||
}
|
||
|
||
[self setupDefaultAlertWithConfig:config];
|
||
}
|
||
|
||
/// default : title + message + cancel + other
|
||
- (void)setupDefaultAlertWithConfig:(MTAlertViewConfig *)config
|
||
{
|
||
_paddingBottom = FIX_SIZE(30);
|
||
_paddingTop = FIX_SIZE(30);
|
||
_contentSize.height = _paddingTop;
|
||
|
||
[self createUI:config.title message:config.message];
|
||
|
||
self.subOverflyButtonHeight = FIX_SIZE(40);
|
||
self.subOverflyButtonLeftRightMargin = FIX_SIZE(20);
|
||
self.subOverflyButtonMargin = FIX_SIZE(14);
|
||
_spacing = FIX_SIZE(8);
|
||
UIView *topBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.width, 6)];
|
||
// topBarView.backgroundColor = RGB_HEX(kThemeBgColor);
|
||
// [self.containerView addSubview:topBarView];
|
||
|
||
if (!config.title || !config.message) { // 无标题 或者无内容
|
||
_titleLabel.y += (topBarView.height + _paddingBottom);
|
||
_messageLabel.y += (topBarView.height + _paddingBottom);
|
||
_contentSize.height = _titleLabel ? _titleLabel.bottom + _titleLabel.y - topBarView.height : _messageLabel.bottom + _messageLabel.y - topBarView.height;
|
||
} else {
|
||
_titleLabel.y += topBarView.height;
|
||
_messageLabel.y += topBarView.height;
|
||
_contentSize.height += topBarView.height;
|
||
}
|
||
|
||
[self createOtherButton:config.otherTitle otherButtonType:config.otherButtonType otherHandler:config.otherHandler cancelTitle:config.cancelTitle cancelButtonType:config.cancelButtonType cancelHandler:config.cancelHandler];
|
||
}
|
||
|
||
/// icon alert : icon + title + message + cancel + other
|
||
- (void)setupIconAlertWithConfig:(MTAlertViewConfig *)config
|
||
{
|
||
UIView *customView = [[UIView alloc] init];
|
||
customView.backgroundColor = [UIColor clearColor];
|
||
|
||
// 用来记录最bottom的view
|
||
UIView *maxBottomView = nil;
|
||
id icon = config.icon;
|
||
if (icon) {
|
||
[self createIconImageWithImage:nil];
|
||
if ([icon isKindOfClass:UIImage.class]) {
|
||
[self.iconImageView setImage:icon];
|
||
} else if ([icon isKindOfClass:[NSString class]]) {
|
||
[self.iconImageView sd_setImageWithURL:[NSURL URLWithString:icon] placeholderImage:ImageNamed(@"guide_placeholder")];
|
||
}
|
||
self.iconImageView.clipsToBounds = YES;
|
||
self.iconImageView.frame = CGRectMake(0, 0, 0, FIX_SIZE(150));
|
||
self.iconImageView.width = FIX_SIZE(320);
|
||
self.iconImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||
[customView addSubview:self.iconImageView];
|
||
maxBottomView = self.iconImageView;
|
||
}
|
||
_contentSize.height = self.iconImageView.bottom + _spacing;
|
||
[self createUI:config.title message:config.message];
|
||
|
||
if (_titleLabel) {
|
||
_titleLabel.top = maxBottomView ? maxBottomView.bottom : _paddingTop + FIX_SIZE(10);
|
||
maxBottomView = _titleLabel;
|
||
}
|
||
if (_messageLabel) {
|
||
_messageLabel.top = (maxBottomView ? maxBottomView.bottom : _paddingTop) + FIX_SIZE(10);
|
||
maxBottomView = _messageLabel;
|
||
}
|
||
|
||
[customView addSubview:_titleLabel];
|
||
[customView addSubview:_messageLabel];
|
||
|
||
customView.size = CGSizeMake(_containerView.width, maxBottomView.bottom + _spacing);
|
||
_contentSize = customView.size;
|
||
|
||
// self.containerView.backgroundColor = [UIColor clearColor];
|
||
customView.layer.cornerRadius = self.containerView.layer.cornerRadius;
|
||
|
||
[self createOtherButton:config.otherTitle otherButtonType:config.otherButtonType otherHandler:config.otherHandler cancelTitle:config.cancelTitle cancelButtonType:config.cancelButtonType cancelHandler:config.cancelHandler];
|
||
|
||
[customView addSubview:self.alertButtonContentView];
|
||
customView.size = CGSizeMake(customView.width, self.alertButtonContentView.bottom + FIX_SIZE(20));
|
||
|
||
[self.containerView addSubview:customView];
|
||
self.customTopView = customView;
|
||
_contentSize.width = customView.width;
|
||
customView.top = _paddingTop;
|
||
customView.centerX = _contentSize.width / 2;
|
||
_contentSize.height = customView.bottom + _paddingTop + _paddingBottom;
|
||
|
||
customView.y = 0;
|
||
self.size = customView.size;
|
||
}
|
||
|
||
/// custom alert : custom view + cancel + other
|
||
- (void)setupCustomAlertWithConfig:(MTAlertViewConfig *)config
|
||
{
|
||
UIView *view = config.customView;
|
||
if (view) {
|
||
if (config.onlyCustomView) {
|
||
[self.containerView addSubview:config.customView];
|
||
self.size = self.contentSize = config.customView.size;
|
||
return;
|
||
}
|
||
[self.containerView addSubview:view];
|
||
self.customTopView = view;
|
||
_contentSize.width = view.width;
|
||
view.top = 0;
|
||
view.centerX = _contentSize.width / 2;
|
||
_contentSize.height = view.bottom + 20;
|
||
}
|
||
self.size = CGSizeMake(_contentSize.width, _contentSize.height);
|
||
|
||
[self createOtherButton:config.otherTitle otherButtonType:config.otherButtonType otherHandler:config.otherHandler cancelTitle:config.cancelTitle cancelButtonType:config.cancelButtonType cancelHandler:config.cancelHandler];
|
||
|
||
if (config.otherTitle || config.cancelTitle) { // 有按钮
|
||
[view addSubview:self.alertButtonContentView];
|
||
self.size = CGSizeMake(view.width, self.alertButtonContentView.bottom);
|
||
[self.containerView addSubview:view];
|
||
self.customTopView = view;
|
||
_contentSize.width = view.width;
|
||
|
||
view.y = 0;
|
||
if (config.customView) {
|
||
for (UIView *subview in self.alertButtonContentView.subviews) {
|
||
subview.y += self.alertButtonContentView.y;
|
||
[self.containerView addSubview:subview];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
- (void)createOtherButton:(NSString *)otherTitle
|
||
otherButtonType:(MTAlertButtonType)type
|
||
otherHandler:(MTAlertButtonHandler)otherHandler
|
||
cancelTitle:(NSString *)cancelButtonTitle
|
||
cancelButtonType:(MTAlertButtonType)cancelType
|
||
cancelHandler:(MTAlertButtonHandler)cancelHandler
|
||
{
|
||
|
||
MTAlertButton *otherButton = nil;
|
||
MTAlertButton *cancelButton = nil;
|
||
|
||
if (otherTitle.length) {
|
||
otherButton = [MTAlertButton buttonWithType:type title:otherTitle handler:otherHandler];
|
||
otherButton.edgeInsets = UIEdgeInsetsMake(_paddingTop-_spacing-FIX_SIZE(6), _paddingLeft, _paddingBottom, _paddingLeft);
|
||
}
|
||
|
||
if (cancelButtonTitle.length) {
|
||
cancelButton = [MTAlertButton buttonWithType:cancelType title:cancelButtonTitle handler:cancelHandler];
|
||
cancelButton.edgeInsets = UIEdgeInsetsMake(_paddingTop-_spacing-FIX_SIZE(6), _paddingLeft, _paddingBottom, _paddingLeft);
|
||
}
|
||
otherButton.edgeInsets = UIEdgeInsetsZero;
|
||
|
||
self.alertButtonContentView.y = _contentSize.height;
|
||
|
||
if (cancelButton && otherButton) {
|
||
[self adjoinWithLeftAction:cancelButton rightAction:otherButton];
|
||
} else {
|
||
if (cancelButton) {
|
||
if (type == MTAlertButtonTypeDefault || type == MTAlertButtonTypeDefaultTheme || type == MTAlertButtonTypeDefaultDestructive) {
|
||
otherButton.edgeInsets = UIEdgeInsetsMake(_paddingTop-_spacing-FIX_SIZE(6), FIX_SIZE(45), 0, FIX_SIZE(45));
|
||
}
|
||
[self addAction:cancelButton];
|
||
} else if (otherButton) {
|
||
if (type == MTAlertButtonTypeDefault || type == MTAlertButtonTypeDefaultTheme || type == MTAlertButtonTypeDefaultDestructive) {
|
||
otherButton.edgeInsets = UIEdgeInsetsMake(_paddingTop-_spacing-FIX_SIZE(6), FIX_SIZE(45), 0, FIX_SIZE(45));
|
||
}
|
||
[self addAction:otherButton];
|
||
// otherButton.layer.cornerRadius = otherButton.height * 0.5;
|
||
} else {
|
||
self.alertButtonContentView.height = _paddingBottom;
|
||
}
|
||
}
|
||
self.alertButtonContentView.height = otherButton.bottom + FIX_SIZE(20);
|
||
}
|
||
|
||
- (void)addAction:(NSString *)actionTitle type:(MTAlertButtonType)type actionHandler:(MTAlertButtonHandler)actionHandler
|
||
{
|
||
MTAlertButton * otherButton = [MTAlertButton buttonWithType:type title:actionTitle handler:actionHandler];
|
||
otherButton.edgeInsets = UIEdgeInsetsMake(5, _paddingLeft, actionTitle ? _spacing : _paddingBottom, _paddingLeft);
|
||
[self addAction:otherButton];
|
||
}
|
||
|
||
- (void)createIconImageWithImage:(UIImage *)icon
|
||
{
|
||
_iconImageView = [[UIImageView alloc]init];
|
||
_iconImageView.size = CGSizeMake(kMTAlertIconDefaultWidth, kMTAlertIconDefaultWidth);
|
||
_iconImageView.centerX = _contentSize.width / 2;
|
||
_iconImageView.top = _paddingTop;
|
||
_iconImageView.image = icon;
|
||
}
|
||
|
||
- (void)createUI:(NSString *)title message:(NSString *)message
|
||
{
|
||
if (title.length) {
|
||
_titleLabel = [[UILabel alloc] init];
|
||
_titleLabel.text = title;
|
||
_titleLabel.numberOfLines = 0;
|
||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||
[self.containerView addSubview:_titleLabel];
|
||
_titleLabel.font = _titleLabelFont;
|
||
_titleLabel.textColor = [UIColor whiteColor];
|
||
|
||
_titleLabel.size = [_titleLabel sizeThatFits:CGSizeMake(_contentSize.width-2*_paddingLeft, MAXFLOAT)];
|
||
_titleLabel.y = _contentSize.height;
|
||
_titleLabel.centerX = _contentSize.width / 2;
|
||
_contentSize.height = _titleLabel.bottom + _spacing;
|
||
}
|
||
|
||
if (message.length) {
|
||
_messageLabel = [[UILabel alloc] init];
|
||
_messageLabel.numberOfLines = 0;
|
||
_messageLabel.font = _messageLabelFont;
|
||
_messageLabel.textAlignment = NSTextAlignmentCenter;
|
||
_messageLabel.textColor = COLOR_WITH_RGB(0xB3B3B3);
|
||
[self.containerView addSubview:_messageLabel];
|
||
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:message];
|
||
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
|
||
paragraphStyle.alignment = NSTextAlignmentCenter;
|
||
paragraphStyle.lineSpacing = 0;
|
||
[string addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, message.length)];
|
||
_messageLabel.attributedText = string;
|
||
|
||
_messageLabel.size = [_messageLabel sizeThatFits:CGSizeMake(_contentSize.width - 2*_paddingLeft, MAXFLOAT)];
|
||
_messageLabel.y = _contentSize.height;
|
||
_messageLabel.centerX = _contentSize.width / 2;
|
||
_contentSize.height = _messageLabel.bottom + _spacing;
|
||
}
|
||
|
||
self.size = CGSizeMake(_contentSize.width, _contentSize.height);
|
||
}
|
||
|
||
- (void)defaultSetup
|
||
{
|
||
// self.backgroundColor = [UIColor clearColor];
|
||
// self.layer.cornerRadius = 10;
|
||
self.clipsToBounds = NO;
|
||
self.subOverflyButtonHeight = MTAlertFixSize(50);
|
||
self.subOverflyButtonLeftRightMargin = MTAlertFixSize(20);
|
||
self.subOverflyButtonMargin = MTAlertFixSize(14);
|
||
|
||
_contentSize.width = kMTAlertContentSizeDefaultWidth; // default width = 320
|
||
_messageLabelFont = MT_FONT_REGULAR_SIZE(15.0);
|
||
_titleLabelFont = MT_FONT_MEDIUM_SIZE(16.0);
|
||
|
||
_paddingTop = MTAlertFixSize(20);
|
||
_paddingBottom = MTAlertFixSize(20);
|
||
_paddingLeft = MTAlertFixSize(20);
|
||
_spacing = MTAlertFixSize(15);
|
||
|
||
_bottomCancelButtonInsets = UIEdgeInsetsMake(MTAlertFixSize(5), 0, 0, MTAlertFixSize(5));
|
||
|
||
self.containerView = [[UIView alloc]initWithFrame:self.bounds];
|
||
self.containerView.clipsToBounds = YES;
|
||
self.alertButtonContentView = [[UIView alloc] init];
|
||
self.alertButtonContentView.width = _contentSize.width;
|
||
self.alertButtonContentView.backgroundColor = [UIColor clearColor];
|
||
[self.containerView addSubview:self.alertButtonContentView];
|
||
[self addSubview:self.containerView];
|
||
|
||
self.containerView.backgroundColor = COLOR_WITH_RGB(0x222436);;
|
||
self.containerView.layer.cornerRadius = 8.0;
|
||
}
|
||
|
||
- (void)setBackgroundColor:(UIColor *)backgroundColor
|
||
{
|
||
[super setBackgroundColor:backgroundColor];
|
||
self.containerView.backgroundColor = backgroundColor;
|
||
self.alertButtonContentView.backgroundColor = backgroundColor;
|
||
}
|
||
|
||
static void *mtAlertViewActionKey = &mtAlertViewActionKey;
|
||
|
||
- (void)clearActions:(NSArray *)subviews {
|
||
for (UIView *subview in subviews) {
|
||
if ([subview isKindOfClass:[MTAlertButton class]]) {
|
||
[subview removeFromSuperview];
|
||
}
|
||
}
|
||
}
|
||
|
||
- (void)addAction:(MTAlertButton *)action
|
||
{
|
||
[self clearActions:self.adjoinActions.allObjects];
|
||
[self.adjoinActions removeAllObjects];
|
||
|
||
[self _injectDismissInBlockAction:action];
|
||
|
||
void (^layout)(CGFloat) = ^(CGFloat top){
|
||
CGFloat width = self.contentSize.width - action.edgeInsets.left - action.edgeInsets.right;
|
||
action.size = CGSizeMake(width, self.subOverflyButtonHeight);
|
||
action.y = top;
|
||
action.centerX = self.contentSize.width / 2;
|
||
};
|
||
|
||
MTAlertButton *lastAction = objc_getAssociatedObject(self, mtAlertViewActionKey);
|
||
if (lastAction) { // current
|
||
if (![action isEqual:lastAction]) layout(lastAction.bottom + action.edgeInsets.top);
|
||
} else { // first
|
||
layout(action.edgeInsets.top);
|
||
}
|
||
|
||
action.verticalLine.hidden = YES;
|
||
[self.alertButtonContentView insertSubview:action atIndex:0];
|
||
objc_setAssociatedObject(self, mtAlertViewActionKey, action, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||
self.alertButtonContentView.height = action.bottom + action.edgeInsets.bottom;
|
||
self.size = CGSizeMake(_contentSize.width, self.alertButtonContentView.bottom + FIX_SIZE(20));
|
||
}
|
||
|
||
//添加按钮点击回调后,处理dismiss
|
||
- (void)_injectDismissInBlockAction:(MTAlertButton *)action
|
||
{
|
||
MTAlertButtonHandler buttonClickedBlock = action.buttonClickedBlock;
|
||
typeof(self) __weak weakSelf = self;
|
||
action.buttonClickedBlock = ^(MTAlertButton *button) {
|
||
typeof(self) strongSelf = weakSelf;
|
||
weakSelf.window.tag = MTWILL_DISMISS_TAG;
|
||
if (buttonClickedBlock) {
|
||
buttonClickedBlock(button);
|
||
}
|
||
if (button.tag == MTNO_DISMISS_TAG) {
|
||
weakSelf.window.tag = 0;
|
||
return;
|
||
}
|
||
if (strongSelf.config.notDismissForever) {
|
||
weakSelf.window.tag = 0;
|
||
return;
|
||
}
|
||
|
||
[strongSelf dismiss];
|
||
};
|
||
}
|
||
|
||
- (void)adjoinWithLeftAction:(MTAlertButton *)leftAction rightAction:(MTAlertButton *)rightAction {
|
||
|
||
[self clearActions:self.subviews];
|
||
|
||
[self _injectDismissInBlockAction:leftAction];
|
||
[self _injectDismissInBlockAction:rightAction];
|
||
|
||
objc_setAssociatedObject(self, mtAlertViewActionKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||
CGFloat leftMargin = self.subOverflyButtonLeftRightMargin;
|
||
CGFloat buttonMargin = self.subOverflyButtonMargin;
|
||
|
||
self.alertButtonContentView.y = _contentSize.height;
|
||
|
||
leftAction.x = leftMargin;
|
||
leftAction.size = CGSizeMake((_contentSize.width - leftMargin * 2 - buttonMargin) / 2.0, self.subOverflyButtonHeight);
|
||
leftAction.y = leftAction.edgeInsets.top;
|
||
|
||
rightAction.frame = leftAction.frame;
|
||
rightAction.x = leftAction.right + buttonMargin;
|
||
rightAction.verticalLine.hidden = NO;
|
||
[self.alertButtonContentView addSubview:leftAction];
|
||
[self.alertButtonContentView addSubview:rightAction];
|
||
self.alertButtonContentView.height = rightAction.bottom + rightAction.edgeInsets.bottom;
|
||
self.adjoinActions = [NSMutableSet setWithObjects:leftAction, rightAction, nil];
|
||
self.size = CGSizeMake(_contentSize.width, self.alertButtonContentView.bottom + FIX_SIZE(20));
|
||
}
|
||
|
||
- (void)layoutSubviews
|
||
{
|
||
[super layoutSubviews];
|
||
|
||
if (self.didLayoutSubviewBlock) {
|
||
self.didLayoutSubviewBlock(self.titleLabel, self.messageLabel, self.iconImageView, self.alertButtonContentView, self.bottomCancelButton, self.customTopView, self.containerView, self);
|
||
}
|
||
}
|
||
|
||
- (void)setFrame:(CGRect)frame
|
||
{
|
||
[super setFrame:frame];
|
||
if (!self.shouldBottomCancelButton) {
|
||
self.containerView.frame = self.bounds;
|
||
}
|
||
}
|
||
|
||
- (void)setShouldBottomCancelButton:(BOOL)shouldBottomCancelButton
|
||
{
|
||
if (self.customTopView && shouldBottomCancelButton) { // 调整使得customTopView屏幕居中
|
||
_paddingTop = KMTAlertBottomCancelTopMargin + kMTAlertBottomCancelButtonWidth;
|
||
self.customTopView.y = _paddingTop;
|
||
self.height = self.customTopView.bottom;
|
||
self.containerView.backgroundColor = [UIColor clearColor];
|
||
}
|
||
|
||
if (_shouldBottomCancelButton != shouldBottomCancelButton) {
|
||
CGFloat fixHeight = 0;
|
||
|
||
if (!self.bottomCancelButton && !_shouldBottomCancelButton) {
|
||
CGFloat s = kMTAlertBottomCancelButtonWidth;
|
||
_bottomCancelButton = [[UIButton alloc]initWithFrame:CGRectMake(0, _bottomCancelButtonInsets.top, s, kMTAlertBottomCancelButtonWidth)];
|
||
[_bottomCancelButton addTarget:self action:@selector(handleRightCancelButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
|
||
_bottomCancelButton.centerX = self.width * 0.5;
|
||
_bottomCancelButton.top = self.height + KMTAlertBottomCancelTopMargin;
|
||
_bottomCancelButton.backgroundColor = [UIColor clearColor];
|
||
[_bottomCancelButton setImage:ImageNamed(@"publish_alert_close") forState:UIControlStateNormal];
|
||
[self addSubview:_bottomCancelButton];
|
||
}
|
||
|
||
fixHeight = _bottomCancelButtonInsets.bottom + _bottomCancelButtonInsets.top + _bottomCancelButton.height + MTAlertFixSize(40);
|
||
CGFloat targetHeight = self.height;
|
||
if (!_shouldBottomCancelButton) {
|
||
targetHeight += fixHeight;
|
||
} else {
|
||
if (_bottomCancelButton) {
|
||
targetHeight -= fixHeight;
|
||
[_bottomCancelButton removeFromSuperview];
|
||
_bottomCancelButton = nil;
|
||
}
|
||
}
|
||
_shouldBottomCancelButton = shouldBottomCancelButton;
|
||
self.height = targetHeight;
|
||
self.popupController.popupView.height = self.height; //父view跟着缩放
|
||
[self setNeedsLayout];
|
||
}
|
||
}
|
||
|
||
- (void)handleRightCancelButtonClicked:(id)sender
|
||
{
|
||
if (self.config.bottomCancelButtonHandler) {
|
||
self.config.bottomCancelButtonHandler(self);
|
||
}
|
||
|
||
if (self.config.notDismissForever) return;
|
||
|
||
[self dismiss];
|
||
}
|
||
|
||
- (zhPopupController *)popupController
|
||
{
|
||
return self.config.popupController;
|
||
}
|
||
|
||
- (MTAlertView *)show
|
||
{
|
||
[[PYAppService currentViewController].view.window endEditing:YES];
|
||
|
||
if (!gShowingAlterViews) {
|
||
gShowingAlterViews = [NSMutableArray array];
|
||
}
|
||
[gShowingAlterViews addObject:self];
|
||
[self showInView:nil];
|
||
self.superview.userInteractionEnabled = YES;
|
||
return self;
|
||
}
|
||
|
||
- (MTAlertView *)showInView:(UIView *)view
|
||
{
|
||
if (!self.config.popupController) {
|
||
zhPopupController *popupController = [[zhPopupController alloc] init];
|
||
popupController.slideStyle = zhPopupSlideStyleShrinkInOut1;
|
||
popupController.allowPan = NO;
|
||
popupController.dismissOnMaskTouched = NO;
|
||
self.config.popupController = popupController;
|
||
}
|
||
|
||
UIWindow *popupWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||
popupWindow.windowLevel = UIWindowLevelAlert;
|
||
PYBaseViewController *vc = [[PYBaseViewController alloc] init];
|
||
vc.mt_nagationBarTransparent = YES;
|
||
vc.view.backgroundColor = [UIColor clearColor];
|
||
popupWindow.rootViewController = [[PYNavigationViewController alloc] initWithRootViewController:vc];
|
||
popupWindow.hidden = NO;
|
||
|
||
if (!gShowingPopupWindows) {
|
||
gShowingPopupWindows = [NSMutableArray array];
|
||
}
|
||
[gShowingPopupWindows addObject:popupWindow];
|
||
UINavigationController *nav = (UINavigationController *)popupWindow.rootViewController;
|
||
view = [nav topViewController] == nav.childViewControllers.firstObject ? [[nav topViewController] view] : nav.view;
|
||
WeakSelf(popupWindow);
|
||
void(^originalDissmissBlock)(zhPopupController *) = [self.popupController.didDismiss copy];
|
||
WeakSelf(self);
|
||
self.popupController.didDismiss = ^(zhPopupController * _Nonnull popupController) {
|
||
if (originalDissmissBlock) {
|
||
originalDissmissBlock(popupController);
|
||
}
|
||
|
||
[gShowingAlterViews removeObject:weakself];
|
||
[gShowingPopupWindows removeObject:weakpopupWindow];
|
||
|
||
if (weakself.didDismiss) {
|
||
weakself.didDismiss(weakself);
|
||
}
|
||
};
|
||
// 显示之前调整窗口
|
||
[self setShouldBottomCancelButton:self.config.shouldBottomCancelButton];
|
||
[self.popupController presentContentView:self duration:0.5 springAnimated:YES inView:view];
|
||
|
||
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
|
||
|
||
return self;
|
||
}
|
||
|
||
- (MTAlertView *)dismiss
|
||
{
|
||
[[[[UIApplication sharedApplication] delegate] window] makeKeyWindow];
|
||
[self.popupController dismiss];
|
||
_config = nil;
|
||
[IQKeyboardManager sharedManager].enableAutoToolbar = YES;
|
||
return self;
|
||
}
|
||
+ (BOOL)hasAlertViewShowing {
|
||
return gShowingAlterViews.count > 0;
|
||
}
|
||
+ (MTAlertView *)showAlertWithCustomView:(UIView *)actionView
|
||
{
|
||
MTAlertView *alerView = [MTAlertView showWithSetupBlcok:^(MTAlertViewConfig *config) {
|
||
config.customView = actionView;
|
||
config.onlyCustomView = YES;
|
||
}];
|
||
return alerView;
|
||
}
|
||
|
||
/// 显示自定义actonView
|
||
+ (zhPopupController *)showActionSheetWithCustomView:(UIView *)actionView {
|
||
|
||
[[PYAppService currentViewController].view.window endEditing:YES];
|
||
zhPopupController *zpPhoupVC = [[zhPopupController alloc] init];
|
||
zpPhoupVC.slideStyle = zhPopupSlideStyleFromBottom;
|
||
zpPhoupVC.layoutType = zhPopupLayoutTypeBottom;
|
||
zpPhoupVC.dismissOnMaskTouched = YES;
|
||
|
||
[zpPhoupVC presentContentView:actionView duration:0.25 springAnimated:NO inView:nil];
|
||
return zpPhoupVC;
|
||
}
|
||
|
||
@end
|