美文网首页
iOS 仿系统UIAlertController高效版

iOS 仿系统UIAlertController高效版

作者: 帅聪哥 | 来源:发表于2018-07-05 21:58 被阅读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

    相关文章

      网友评论

          本文标题:iOS 仿系统UIAlertController高效版

          本文链接:https://www.haomeiwen.com/subject/vujmuftx.html