iOS 仿系统UIAlertController高效版

2018-07-05  本文已影响222人  帅聪哥

最近封装了一个AlertController,完全按照系统的思路进行封装,省去了学习成本,且自定义程度远远高于系统的。说不多说,上代码咯!
下载地址先附上

#import <UIKit/UIKit.h>

/**样式*/
@interface BDNomalAlertActionStyle : NSObject

/**标题颜色*/
@property (nonatomic,strong)UIColor *titleColor;
/**标题大小*/
@property (nonatomic,strong)UIFont *titleFont;
/**背景色*/
@property (nonatomic,strong)UIColor *bgColor;

@end

@interface BDNomalAlertAction : NSObject

@property (nonatomic,strong,readonly)BDNomalAlertActionStyle *style;
@property (nonatomic,copy,readonly)NSString *title;

+ (instancetype)actionWithTitle:(NSString *)title style:(BDNomalAlertActionStyle*)style handler:(void (^)(BDNomalAlertAction *action))handler;

@end

@interface BDNomalAlertView : UIView

+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message;

/**之间的距离 默认为10*/
@property (nonatomic,assign)CGFloat actionBtnMargin;
/**左右两边的间距 默认为0*/
@property (nonatomic,assign)CGFloat actionBtnLeftInset;
/**展示按钮的最大宽度,主要是为了美观*/
@property (nonatomic,assign,readonly)CGFloat actionBtnMaxWidth;
- (void)addAction:(BDNomalAlertAction *)action;

- (void)showAlertView;

@end

各位小伙伴们,是不是跟系统的一样样的。动画效果高仿系统的。

一共分为三个类:

/**
这个是样式模型,决定了你的操作按钮长的样子,开发者还可以继续添加属性即可
*/
@interface BDNomalAlertActionStyle : NSObject

而且提供了最常规的样式类方法快速创建

/**取消样式*/
+ (instancetype)cancelNomalStyle;
/**确定样式*/
+ (instancetype)sureNomalStyle;

第二个是操作Action,也是仿照了系统进行设计的,以下是代码:

@interface BDNomalAlertAction ()

@property (nonatomic,copy)void (^actionHandler)(BDNomalAlertAction*action);

@end

@implementation BDNomalAlertAction

+ (instancetype)actionWithTitle:(NSString *)title style:(BDNomalAlertActionStyle*)style handler:(void (^)(BDNomalAlertAction *action))handler
{
    return [[BDNomalAlertAction alloc]initWithTitle:title style:style handler:handler];
}

-(instancetype)initWithTitle:(NSString*)title style:(BDNomalAlertActionStyle*)style handler:(void (^)(BDNomalAlertAction *action))handler
{
    self = [super init];
    if(self){
        _title = title;
        _style = style;
        _actionHandler = handler;
    }
    return self;
}

@end

BDNomalAlertView是最关键的了,不废话了,直接上了,

@interface BDNomalAlertView ()

@property (nonatomic,weak)UIView *contentView;
@property (nonatomic,weak)UIView *actionView;
@property (nonatomic,strong)NSMutableArray *actionArray;

@end

@implementation BDNomalAlertView

+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message
{
    return [[BDNomalAlertView alloc]initWithFrame:[UIScreen mainScreen].bounds title:title message:message];
}

-(NSMutableArray *)actionArray
{
    if(!_actionArray){
        _actionArray = [NSMutableArray array];
    }
    return _actionArray;
}

-(instancetype)initWithFrame:(CGRect)frame title:(NSString*)title message:(NSString *)message
{
    self = [super initWithFrame:frame];
    if(self){
        _actionBtnMargin = 10;
        _actionBtnLeftInset = 0;
        _actionBtnMaxWidth = 100;
        self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4];
        CGFloat contentWidth = 250;
        if(SCREEN_WIDTH == 375){
            contentWidth = 280;
        }else if (SCREEN_WIDTH > 375){
            contentWidth = 320;
        }
        
        CGFloat contentActionHeight = 70;
        CGFloat contentTitleHeight = 0;
        CGFloat contentMessageHeight = 0;
        if(title.length > 0){
            contentTitleHeight = [title boundingRectWithSize:CGSizeMake(contentWidth-2*ALERT_LEFT_MARGIN, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont boldSystemFontOfSize:15]} context:nil].size.height+2+2*12;
        }
        if(message.length >0){
            contentMessageHeight = [message boundingRectWithSize:CGSizeMake(contentWidth-2*ALERT_LEFT_MARGIN, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil].size.height+2+2*15;
        }
        CGFloat contentHeight = contentActionHeight+contentTitleHeight+contentMessageHeight;
        UIView *contentView = [[UIView alloc]initWithFrame:CGRectMake((frame.size.width-contentWidth)*0.5, (frame.size.height-contentHeight)*0.5, contentWidth, contentHeight)];
        contentView.backgroundColor = [UIColor whiteColor];
        self.contentView = contentView;
        [self addSubview:contentView];
        [contentView.layer setCornerRadius:5];
        [contentView.layer setMasksToBounds:YES];

        CGRect titleViewFrame = CGRectZero;
        CGRect messageViewFrame = CGRectZero;
        CGRect actionViewFrame = CGRectZero;
        //添加标题
        if(contentTitleHeight != 0){
            titleViewFrame = CGRectMake(0, 0, contentWidth, contentTitleHeight);
            actionViewFrame = CGRectMake(0, CGRectGetMaxY(titleViewFrame), contentWidth, contentActionHeight);
            UIView *titleView = [[UIView alloc]initWithFrame:titleViewFrame];
            [contentView addSubview:titleView];
            
            UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(ALERT_LEFT_MARGIN, 12, titleView.width-2*ALERT_LEFT_MARGIN, titleView.height-2*12)];
            titleLabel.textColor = [UIColor colorWithRed:1.0*51/255 green:1.0*51/255 blue:1.0*51/255 alpha:1.0];
            titleLabel.font = [UIFont boldSystemFontOfSize:15];
            titleLabel.text = title;
            titleLabel.numberOfLines = 0;
            titleLabel.textAlignment = NSTextAlignmentCenter;
            [titleView addSubview:titleLabel];
            
            UIView *titleLine = [[UIView alloc]initWithFrame:CGRectMake(0, titleView.height-0.8, titleView.width, 0.8)];
            titleLine.backgroundColor = [UIColor colorWithRed:1.0*225/255 green:1.0*225/255 blue:1.0*225/255 alpha:1.0];
            [titleView addSubview:titleLine];
        }
        //添加内容
        if(contentMessageHeight != 0){
            messageViewFrame = CGRectMake(0, CGRectGetMaxY(titleViewFrame), contentWidth, contentMessageHeight);
            actionViewFrame = CGRectMake(0, CGRectGetMaxY(messageViewFrame), contentWidth, contentActionHeight);
            UIView *messageView = [[UIView alloc]initWithFrame:messageViewFrame];
            [contentView addSubview:messageView];
            
            UILabel *messageLabel = [[UILabel alloc]initWithFrame:CGRectMake(ALERT_LEFT_MARGIN, 15, messageView.width-2*ALERT_LEFT_MARGIN, messageView.height-2*15)];
            messageLabel.numberOfLines = 0;
            messageLabel.textColor = [UIColor colorWithRed:1.0*102/255 green:1.0*102/255 blue:1.0*102/255 alpha:1.0];;
            messageLabel.textAlignment = NSTextAlignmentCenter;
            messageLabel.text = message;
            messageLabel.font = [UIFont systemFontOfSize:14];
            [messageView addSubview:messageLabel];
        }
        UIView *actionView = [[UIView alloc]initWithFrame:actionViewFrame];
        self.actionView = actionView;
        [contentView addSubview:actionView];
        
    }
    return self;
}


- (void)addAction:(BDNomalAlertAction *)action
{
    [self.actionArray addObject:action];
    NSInteger actionIndex = self.actionView.subviews.count;
    BDUnHightedBtn *button = [[BDUnHightedBtn alloc]init];
    button.tag = actionIndex;
    BDNomalAlertActionStyle *style = action.style;
    [button setTitle:action.title forState:UIControlStateNormal];
    UIFont *btnFont = [UIFont systemFontOfSize:15];
    UIColor *btnColor = [UIColor colorWithRed:1.0*51/255 green:1.0*51/255 blue:1.0*51/255 alpha:1.0];
    if(style.titleFont){
        btnFont = style.titleFont;
    }
    if(style.titleColor){
        btnColor = style.titleColor;
    }
    
    button.titleLabel.font = btnFont;
    [button setTitleColor:btnColor forState:UIControlStateNormal];
    if(style.bgColor){
        [button setBackgroundColor:style.bgColor];
    }
    [button.layer setCornerRadius:3];
    [button.layer setMasksToBounds:YES];
    [self.actionView addSubview:button];
    [button addTarget:self action:@selector(clickActionButton:) forControlEvents:UIControlEventTouchUpInside];
    
}

- (void)clickActionButton:(BDUnHightedBtn*)button
{
    BDNomalAlertAction *action = self.actionArray[button.tag];
    WEAK_SELF(action);
    if(action.actionHandler){
        action.actionHandler(weakaction);
    }
    [self dismissAnimation];
}

- (void)showAlertView
{
    //设置actionview中的button的frame
    NSInteger count = self.actionView.subviews.count;
    CGFloat leftInset = _actionBtnLeftInset;
    
    CGFloat actionBtnWidth = (self.actionView.width - ((count-1)*_actionBtnMargin)-(2*leftInset))/count;
    if(actionBtnWidth >_actionBtnMaxWidth){
        actionBtnWidth = _actionBtnMaxWidth;
        //那么需要调整初始x
       leftInset = (self.actionView.width - (actionBtnWidth*count+ (count-1)*_actionBtnMargin))*0.5;
    }
    
    CGFloat actionBtnHeight = self.actionView.height-2*15;
    for (int i = 0; i<self.actionView.subviews.count; i++) {
        CGFloat actionBtnX = leftInset+(actionBtnWidth+_actionBtnMargin)*I;
        BDUnHightedBtn *button = self.actionView.subviews[I];
        button.frame = CGRectMake(actionBtnX, 15, actionBtnWidth, actionBtnHeight);
    }
    [self animationAlert:self.contentView];
    [[UIApplication sharedApplication].keyWindow addSubview:self];
    
}


- (void)animationAlert:(UIView *)view
{
    CAKeyframeAnimation *popAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    popAnimation.duration = 0.25;
    popAnimation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2f, 1.2f, 1.0f)],
                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.0f)],
                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.05f, 1.05f, 1.05f)],
                            [NSValue valueWithCATransform3D:CATransform3DIdentity]];
    popAnimation.keyTimes = @[@0.0f, @0.2f, @0.4f, @1.0f];
    popAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                                     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],
                                     [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [view.layer addAnimation:popAnimation forKey:nil];
    
}

- (void)dismissAnimation
{
    [UIView animateWithDuration:0.25 animations:^{
        self.alpha = 0;
    }];
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    scaleAnimation.toValue = [NSNumber numberWithFloat:0.4];
    scaleAnimation.duration = 0.3f;
    scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.contentView.layer addAnimation:scaleAnimation forKey:nil];
    [BDPublicWays outTimeShow:0.25 action:^{
        [self removeFromSuperview];
    }];
}

点击这里下载
放心,能够正常释放,不存在内存泄露!喜欢的话,点个赞吧

下面是效果图


IMG_0526.PNG
上一篇下一篇

猜你喜欢

热点阅读