iOS-CJJTimer 高性能倒计时工具(短信、商品秒杀)

  • 在平时开发中,多多少少都会用到定时器,获取短信验证码、商品秒杀倒计时等等,如果每次都去写一堆定时器代码不仅麻烦而且如果操作不慎还会造成内存泄漏;所以,封装一个简单好用+安全+高性能的定时器是非常有必要的。
  • 在业余时间我封装了CJJTimer,关于定时器的选用,iOS目前为我们提供了NSTimerCADisplayLinkGCD三种定时器,关于他们的区别和用法本文不再阐述,网上可以找到一堆介绍得非常详细的文章,而CJJTimer采用了GCD定时器
  • GCD定时器主要优点:准时,高性能
  • demo模仿淘宝,京东,苏宁易购,拼多多首页倒计时的UI以及简单的短信倒计时效果,这些是通过CJJTimer来绘制的,直接上图看效果
各种倒计时效果(动态)

CJJTimer

CJJTimer是一个简单好用的定时器工具(适用于短信倒计时、商品秒杀倒计时等等常见场景)

github地址

https://github.com/JimmyCJJ/CJJTimer

文件结构

文件结构

How To Add CJJTimer?

  • 手动管理
下载demo,直接把demo里的文件夹CJJTimer拖进工程即可
  • CocoaPods管理
pod 'CJJTimer'

#import

在需要用到的地方导入对应的头文件

#import 

How To Use CJJTimer?

CJJTimer主要有两大模块

  • 一个是CJJTimerView,用于处理时间(天时分秒、时分秒、时分、分秒)倒计时
  • 另一个是CJJSMSTimer,用于处理短信倒计时

CJJTimerView

拿上图中的淘宝倒计时做例子
我们把倒计时view放在cell里面

  • 1.在cell里持有CJJTimerView
@property (nonatomic, strong) CJJTimerView *timer;
  • 2.懒加载配置CJJTimerView
    通过一个配置类CJJTimerViewConfiguration配置好所有的功能和UI属性,直接赋给CJJTimerView即可,任意时机设置timerLastTime(时间戳,假设现在是7月26号中午12:00,我想要倒数到第二天也就是7月27号的中午12:00,那么就把timerLastTime设置为第二天的中午12:00的对应时间戳,一般由后台返回)即可自动转换成到目标时间戳的剩余时分秒

支持链式语法调用

- (CJJTimerView *)timer{
    if(!_timer){
        CJJTimerViewConfiguration *configuration = [CJJTimerViewConfiguration configureTimerView];
        configuration.viewWidth(18)
        .viewHeight(18)
        .hiddenWhenFinished(NO)
        .lastTime([NSString stringWithFormat:@"%ld",[self getNowTimeTimeStampSec].integerValue+10])
        .cornerRadius(3)
        .backgroundColor([UIColor colorWithRed:238/255.0 green:39/255.0 blue:5/255.0 alpha:1])
        .textLabelFont([UIFont systemFontOfSize:11 weight:UIFontWeightBold])
        .textLabelColor([UIColor whiteColor])
        .colonLabelFont([UIFont systemFontOfSize:11 weight:UIFontWeightBold])
        .colonLabelColor([UIColor colorWithRed:238/255.0 green:39/255.0 blue:5/255.0 alpha:1]);

        _timer = [CJJTimerView timerViewWithConfiguration:configuration];
        _timer.delegate = self;
    }
    return _timer;
}
  • 3.布局CJJTimerView

提供一个接口返回配置好的CJJTimerView的宽和高

/// 自动布局
/// @param layout 此block会返回自动计算后的timerView的width和height,可用于布局
- (void)configureLayout:(CJJTimerViewLayout)layout;

然后只需要配置x和y的布局即可(此处不需要weakSelf,内部不持有block,不存在循环引用)

[self.timer configureLayout:^(CGFloat timerWidth, CGFloat timerHeight) {
        [self.timer mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(self.titleL.mas_right).offset(5);
            make.centerY.mas_equalTo(0);
            make.size.mas_equalTo(CGSizeMake(timerWidth, timerHeight));
        }];
    }];
  • 4. 开启倒计时
    默认开启定时器
/// 是否自动开启定时器,默认YES
@property (nonatomic, assign, getter=isTimerAutoStart) BOOL timerAutoStart;

如果想手动开启,配置时把该属性设为NO

configuration.timerAutoStart = NO;

然后在适当的时机调用

/// 开启定时器
- (dispatch_source_t)startTimer;
  • 5. 销毁倒计时
    内部会自动销毁定时器,不需要手动去销毁,如果需要控制销毁的时机的话,也可以调用
/// 销毁定时器(如果想手动控制销毁的时机请调用此方法,否则自动销毁)
- (void)stopTimer;

关于更多细节请直接看demo

CJJSMSTimer

#import 

NS_ASSUME_NONNULL_BEGIN

typedef void (^CJJSMSTimerVoidBlock)(void);
typedef void (^CJJSMSTimerSecBlock)(int sec);

@interface CJJSMSTimer : NSObject

/// 开启倒计时 - 完全自定义回调
/// @param btn 传入按钮对象
/// @param timeOut 传入倒数总时间
/// @param ingBlock 倒数进行时的设置
/// @param finishedBlock 倒数结束后的设置
+ (instancetype)timerStartCountdownWithBtn:(UIButton *)btn
                               timeOut:(int)timeOut
                    titleIngSettingBlock:(CJJSMSTimerSecBlock __nullable)ingBlock
                  titleFinishSettingBlock:(CJJSMSTimerVoidBlock __nullable)finishedBlock;

/// 开启倒计时 - 默认回调
/// @param btn 传入按钮对象
/// @param timeOut 传入倒数总时间
/// @param ingTitle 倒数进行时的标题
/// @param ingTitleColor 倒数进行时的标题颜色
/// @param finishedTitle 倒数结束后的标题
/// @param finishedTitleColor 倒数结束后的标题颜色
/// @param ingBlock 倒数进行时的设置
/// @param finishedBlock 倒数结束后的设置
+ (instancetype)timerStartCountdownWithBtn:(UIButton *)btn
                               timeOut:(int)timeOut
                               ingTitle:(NSString *)ingTitle
                           ingTitleColor:(UIColor *)ingTitleColor
                           finishedTitle:(NSString *)finishedTitle
                       finishedTitleColor:(UIColor *)finishedTitleColor
                      titleIngSettingBlock:(CJJSMSTimerSecBlock __nullable)ingBlock
                    titleFinishSettingBlock:(CJJSMSTimerVoidBlock __nullable)finishedBlock;


/// 销毁定时器(如果想手动控制销毁的时机请调用此方法,否则自动销毁)
- (void)destroyTimer;
@end
  • 适用于UIButton,头文件提供2个接口

使用方法

  • 1.持有CJJSMSTimer
@property (nonatomic, strong) CJJSMSTimer *timer;
  • 2.在自定义Button的点击事件或者其他时机调用接口提供的方法
- (void)startCountDownAction:(UIButton *)btn{
    BOOL isCustom = NO;
    
    //block设置倒计时前后UI变化
    if(isCustom){
        self.timer = [CJJSMSTimer timerStartCountdownWithBtn:btn timeOut:6 titleIngSettingBlock:^(int sec) {
            [btn setTitle:[NSString stringWithFormat:@"%ds",sec] forState:UIControlStateNormal];
            [btn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
            btn.layer.borderColor = [UIColor grayColor].CGColor;
        } titleFinishSettingBlock:^{
            [btn setTitle:@"获取验证码" forState:UIControlStateNormal];
            [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
            btn.layer.borderColor = [UIColor blueColor].CGColor;
        }];
    }else{
        //默认设置方法
        self.timer = [CJJSMSTimer timerStartCountdownWithBtn:btn timeOut:6 ingTitle:@"重新获取" ingTitleColor:[UIColor grayColor] finishedTitle:@"获取验证码" finishedTitleColor:[UIColor blueColor] titleIngSettingBlock:^(int sec) {
            btn.layer.borderColor = [UIColor grayColor].CGColor;
        } titleFinishSettingBlock:^{
            btn.layer.borderColor = [UIColor blueColor].CGColor;
        }];
    }
}

以上代码展示了两种不同的设置方法,实际使用中选择其中一种方式即可

  • 3.定时器销毁
    原理同上,内部自动销毁,如有需要手动销毁请调用
/// 销毁定时器(如果想手动控制销毁的时机请调用此方法,否则自动销毁)
- (void)destroyTimer;

具体细节请看demo


2021.06.22 版本更新
CJJTimer 2.0.2
支持天时分秒,支持自动切换类型,取消对第三方布局库Masonry的依赖,优化代码


代码细节中如有不足请随意提出评论,如果有更好的实现方法,欢迎联系我一起交流~

你可能感兴趣的:(iOS-CJJTimer 高性能倒计时工具(短信、商品秒杀))