OC插屏红包带动画快速实现

2017-09-07  本文已影响15人  硅谷干货

因为项目需求,自定义弹出视图的基础上加一些用户体验更佳的动画和友情文字以及图片提示等,就有了写了这篇博客,一为方便自己以后在其他项目中复用二为更多开发者拷贝使用,若有书写代码不足之处欢迎批评指正。

先看下我的Demo示例运行效果图如下:

弹窗动态效果图.gif

实现文件只有一个类:(QDBonusAlertView.h 和 QDBonusAlertView.m)

1. QDBonusAlertView.h头文件代码如下:

#import <UIKit/UIKit.h>

@interface QDBonusAlertView : UIView

//设置遮罩蒙板响应事件是否关闭
@property (nonatomic, assign) BOOL closeUserInteractionEnabled;

//初始化
+ (instancetype)alertWithFrame:(CGRect)frame imageName:(NSString *)imageName message:(NSString *)message state:(NSString *)state confirmStr:(NSString *)confirmStr tapBlock:(void (^)())tapBlock;

//弹窗
- (void)alert;

@end

2. QDBonusAlertView.m实现文件代码如下:

#import "QDBonusAlertView.h"

const CGFloat bonusAlertViewWidthRatio = 0.655;  //宽度系数
const CGFloat bonusAlertViewHeightRatio = 0.316; //高度系统

@interface QDBonusAlertView ()
@property (nonatomic, weak) UIView *bgView;
@property (nonatomic, weak) UIImageView *bgImageView;
@property (nonatomic, weak) UIImageView *iconImageView;//顶部icon图
@property (nonatomic, weak) UIImageView *textImageView;//文本图片
@property (nonatomic, weak) UILabel *messageLabel;//消息内容
@property (nonatomic, weak) UILabel *stateL;//说明
@property (nonatomic, weak) UIButton *confirmButton;//确认按钮
@property (nonatomic, weak) UIButton *closeButton;//关闭按钮

@property (nonatomic, copy) NSString *message;
@property (nonatomic, copy) NSString *state;
@property (nonatomic, copy) NSString *imageName;
@property (nonatomic, copy) NSString *confirmStr;//确认按钮

@property (nonatomic, copy) void(^tapBlock)();

@end

@implementation QDBonusAlertView

+ (instancetype)alertWithFrame:(CGRect)frame imageName:(NSString *)imageName message:(NSString *)message state:(NSString *)state confirmStr:(NSString *)confirmStr tapBlock:(void (^)())tapBlock{
    QDBonusAlertView *alert = [[self alloc] initWithFrame:frame];
    alert.tapBlock = tapBlock;
    alert.imageName = imageName;
    alert.message = message;
    alert.state = state;
    alert.confirmStr = confirmStr;
    return alert;
}

- (void)alert{
    [QDKeyWindow addSubview:self];
}

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self setUpUI];
    }
    return self;
}

- (void)setUpUI{
    
    //半透明遮盖视图(满屏)
    UIView *bgView = [[UIView alloc] initWithFrame:UIApplication.sharedApplication.keyWindow.bounds];
    bgView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
    bgView.alpha =0;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(bgViewTapped)];
    [bgView addGestureRecognizer:tap];
    [self addSubview:bgView];
    self.bgView = bgView;
    
    //背景图片视图
    UIImageView *bgImageView = [[UIImageView alloc] init];
    bgImageView.backgroundColor = [UIColor whiteColor];
    [bgImageView setUserInteractionEnabled:YES];
    bgImageView.layer.cornerRadius = 4;
    [self addSubview:bgImageView];
    self.bgImageView = bgImageView;
    
    //顶部标题视图
    UIImageView *iconImageView = [[UIImageView alloc] init];
    iconImageView.backgroundColor = [UIColor clearColor];
    [self.bgImageView addSubview:iconImageView];
    self.iconImageView = iconImageView;
    
    //文字图片
    UIImageView *textImageView = [[UIImageView alloc] init];
    textImageView.contentMode = UIViewContentModeCenter;
    textImageView.image = [UIImage imageNamed:@"img_alert_bonus_text"];
    [self.bgImageView addSubview:textImageView];
    self.textImageView = textImageView;
    
    //消息内容
    UILabel *messageLabel = [[UILabel alloc] init];
    messageLabel.textAlignment = NSTextAlignmentCenter;
    messageLabel.font = QDFont13;
    messageLabel.textColor = QDColorCSS("#817DB3");
    messageLabel.numberOfLines = 2;
    [self.bgImageView addSubview:messageLabel];
    self.messageLabel = messageLabel;
    
    //说明文内容
    UILabel *stateL = [[UILabel alloc] init];
    stateL.textAlignment = NSTextAlignmentCenter;
    stateL.font = [UIFont boldSystemFontOfSize:14];
    stateL.textColor = QDColorCSS("#330000");
    stateL.numberOfLines = 2;
    [self.bgImageView addSubview:stateL];
    self.stateL = stateL;
    
    //确定按钮
    UIButton *confirmButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [confirmButton setTitle:@"确定" forState:UIControlStateNormal];
    [confirmButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [confirmButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
    [confirmButton setBackgroundImage:[UIImage imageNamed:@"img_alert_bonus_btn"] forState:UIControlStateNormal];
    [confirmButton setBackgroundColor:QDColorButtonHighlight forState:UIControlStateHighlighted];
    [confirmButton.titleLabel setFont:QDFont18];
    [confirmButton roundViewWithRadius:20];
    [confirmButton addTarget:self action:@selector(confirmButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    [self.bgImageView addSubview:confirmButton];
    self.confirmButton = confirmButton;
    
    //关闭按钮
    UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    closeButton.contentMode = UIViewContentModeCenter;
    [closeButton setBackgroundImage:[UIImage imageNamed:@"img_alert_close_normal"] forState:UIControlStateNormal];
    [closeButton addTarget:self action:@selector(closeButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:closeButton];
    self.closeButton = closeButton;
    
    if (UIDevice.currentDevice.systemVersion.doubleValue < 9.0) {
        [UIView animateWithDuration:0.2 animations:^{
            self.bgView.alpha = 1;
            CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
            scaleAnimation.fromValue = [NSNumber numberWithFloat:0.7] ;
            scaleAnimation.toValue = [NSNumber numberWithFloat:1.0] ;
            scaleAnimation.duration = 0.1;
            scaleAnimation.autoreverses = NO;
            [self.bgImageView.layer addAnimation:scaleAnimation forKey:@"transform.scale"];
        }];
    }else{
        CASpringAnimation *scaleAnimation = [CASpringAnimation animationWithKeyPath:@"transform.scale"];
        scaleAnimation.damping = 5;
        scaleAnimation.stiffness = 100;
        scaleAnimation.mass = 0.35;
        scaleAnimation.fromValue = [NSNumber numberWithFloat:0.7] ;
        scaleAnimation.toValue = [NSNumber numberWithFloat:1.0] ;
        scaleAnimation.duration = scaleAnimation.settlingDuration;
        scaleAnimation.autoreverses = NO;
        [self.bgImageView.layer addAnimation:scaleAnimation forKey:@"transform.scale"];
        [UIView animateWithDuration:0.2 animations:^{
            self.bgView.alpha = 1;
        }];
    }
}

- (void)layoutSubviews{
    [super layoutSubviews];
    
    //内容宽高
    CGFloat contentW = [UIScreen mainScreen].bounds.size.width * bonusAlertViewWidthRatio;
    CGFloat contentH = [UIScreen mainScreen].bounds.size.height * bonusAlertViewHeightRatio;
    
    [self.bgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.size.mas_equalTo(CGSizeMake(contentW, contentH));
        make.center.mas_equalTo(self);
    }];
    
    [self.iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.bgImageView);
        make.centerY.equalTo(self.bgImageView.mas_top);
    }];
    
    [self.textImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.bgImageView);
        make.top.mas_equalTo(self.iconImageView.mas_bottom).mas_offset(10);
    }];
    
    [self.messageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.bgImageView);
        make.top.mas_equalTo(self.textImageView.mas_bottom).mas_offset(20);
        make.left.mas_equalTo(self.bgImageView).mas_offset(20);
        make.right.mas_equalTo(self.bgImageView.mas_right).mas_equalTo(-20);
    }];
    
    [self.stateL mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self.bgImageView);
        make.top.mas_equalTo(self.messageLabel.mas_bottom).mas_offset(5);
        make.left.mas_equalTo(self.bgImageView).mas_offset(20);
        make.right.mas_equalTo(self.bgImageView.mas_right).mas_equalTo(-20);
    }];
    
    [self.confirmButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(self.bgImageView);
        make.bottom.mas_equalTo(self.bgImageView.mas_bottom).mas_offset(-15);
        make.size.mas_equalTo(CGSizeMake(contentW * bonusAlertViewWidthRatio, 40));
    }];
    
    [self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(self);
        make.top.mas_equalTo(self.bgImageView.mas_bottom).mas_equalTo(30);
    }];
}

#pragma mark -按钮点击事件-
- (void)confirmButtonTapped{
    if (self.tapBlock) {
        self.tapBlock();
    }
    [UIView animateWithDuration:0.15 animations:^{
        self.bgView.alpha = 0;
        [self.bgImageView.layer removeAllAnimations];
        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0] ;
        scaleAnimation.toValue = [NSNumber numberWithFloat:0.5] ;
        scaleAnimation.duration = 0.15;
        scaleAnimation.autoreverses = NO;
        [self.bgImageView.layer addAnimation:scaleAnimation forKey:@"transform.scale"];
    }];
    [self performSelector:@selector(removeSelf) withObject:nil afterDelay:0.12];
}

//点击遮罩视图
- (void)bgViewTapped{
    if (!self.closeUserInteractionEnabled) [self closeButtonTapped];
}

- (void)closeButtonTapped{
    
    [UIView animateWithDuration:0.15 animations:^{
        self.bgView.alpha = 0;
        [self.bgImageView.layer removeAllAnimations];
        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0] ;
        scaleAnimation.toValue = [NSNumber numberWithFloat:0.5] ;
        scaleAnimation.duration = 0.15;
        scaleAnimation.autoreverses = NO;
        [self.bgImageView.layer addAnimation:scaleAnimation forKey:@"transform.scale"];
    }];
    [self performSelector:@selector(removeSelf) withObject:nil afterDelay:0.12];
}

- (void)removeSelf{
    [self removeFromSuperview];
}

- (void)setImageName:(NSString *)imageName{
    _imageName = imageName;
    self.iconImageView.image = [UIImage imageNamed:imageName];
}

- (void)setMessage:(NSString *)message{
    _message = message;
    self.messageLabel.text = message;
}

- (void)setState:(NSString *)state{
    _state = state;
    self.stateL.text = state;
}

- (void)setConfirmStr:(NSString *)confirmStr{
    _confirmStr = confirmStr;
    //默认“确定”
    if (confirmStr) {
        [self.confirmButton setTitle:confirmStr forState:UIControlStateNormal];
    }
}

@end

3.调用方式:

QDBonusAlertView *alertView = [QDBonusAlertView alertWithFrame:self.view.window.bounds imageName:@"img_alert_bonus_normal" message:@"恭喜你已获得2枚新手专享红包" state:@"普通区红包x1,普通区红包x1" confirmStr:@"查看红包" tapBlock:^{
        
    }];
    [alertView alert];

注意:有的项目中有需求背景遮罩蒙板不让用户点击,只需要创建QDBonusAlertView对象之后,设置属性closeUserInteractionEnabled = YES即可实现。

如果您希望在你的项目中直接使用,那就直接拷贝就行
如果觉得还不够具体,后期考虑将代码上传github与分享源码,希望深层交流的童鞋加我qq:1107160410,我们一起探讨,感谢您看到这里,如方便的话点个赞,我会更加努力。

上一篇下一篇

猜你喜欢

热点阅读