OC插屏紅包帶動畫快速實現

因為項目需求,自定義彈出視圖的基礎上加一些用戶體驗更佳的動畫和友情文字以及圖片提示等,就有了寫了這篇博客,一為方便自己以后在其他項目中復用二為更多開發者拷貝使用,若有書寫代碼不足之處歡迎批評指正。

先看下我的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與分享源碼,如果能幫到你,麻煩幫我點個贊,我會更加努力。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容