1、需要Xcode8开发环境
2、本例支持iOS8+
3、本例实现的功能:一句代码在任何界面实现一个全屏倒计时
这是我的工程结构,把箭头指向的文件夹拖入你的工程
然后需在你的工程中用到的地方倒入头文件#import "WZBCountdownButton.h"
,在需要开始倒计时的地方使用[WZBCountdownButton play]
然后按command + R运行即可!
代码如下:
效果如下:
因为+play方法默认执行倒计时3秒,如果想定制倒计时时间,请使用[WZBCountdownLabel playWithNumber:5];效果如下:
有的需求可能是这样:在倒计时结束后我想实现一句话,请使用[WZBCountdownLabel playWithNumber:5 endTitle:@"GO!"];
效果如下:
此外,我在代码里增加了对当前倒计时状态的监听,提供两种方式,block和代理。方法一是你可以通过实现一下两个block来监听倒计时状态:
/** 倒计时完成时调的block */ typedef void(^CountdownSuccessBlock)(WZBCountDownButton *button); /** 倒计时开始时调的block */ typedef void(^CountdownBeginBlock)(WZBCountDownButton *button);
或者通过[WZBCountdownButton addDelegate:self]; 添加代理,然后实现一下两个代理方法
/** 倒计时完成时调用 */ - (void)countdownSuccess:(WZBCountDownButton *)button { NSLog(@"倒计时完成"); } /** 倒计时开始时调用 */ - (void)countdownBegin:(WZBCountDownButton *)button { NSLog(@"倒计时开始"); }
除此之外,我还定义了方法,可以倒计时图片,就是把一堆图片,一秒一个的播放,如下:
[WZBCountDownButton playWithImages:imageNames begin:^(WZBCountDownButton *button) { NSLog(@"倒计时开始"); } success:^(WZBCountDownButton *button) { NSLog(@"倒计时结束"); }];
效果如下:
以下是几个开始倒计时的方法:
#pragma mark - play methods + (instancetype)play { return [self playWithNumber:0]; } + (instancetype)playWithNumber:(NSInteger)number { return [self playWithNumber:number endTitle:[WZBCountDownButton share].endTitle]; } + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle { return [self playWithNumber:number endTitle:endTitle success:[WZBCountDownButton share].countdownSuccessBlock]; } + (instancetype)playWithNumber:(NSInteger)number success:(CountdownSuccessBlock)success { return [self playWithNumber:number endTitle:[WZBCountDownButton share].endTitle success:success]; } + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle success:(CountdownSuccessBlock)success{ return [self playWithNumber:number endTitle:endTitle begin:[WZBCountDownButton share].countdownBeginBlock success:success]; }
上面这几个方法最终都会走到下边这个方法,核心代码:
+ (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success { // isAnimationing 用来判断目前是否在动画 if (isAnimationing) return nil; WZBCountDownButton *button = [WZBCountDownButton share]; [button setImage:[UIImage new] forState:UIControlStateNormal]; button.countDownType = WZBCountDownNumber; button.hidden = NO; // 给全局属性赋值 // 默认三秒 button.number = 3; if (number && number > 0) button.number = number; if (endTitle) button.endTitle = endTitle; if (success) button.countdownSuccessBlock = success; if (begin) button.countdownBeginBlock = begin; [self setupButtonBase:button]; // 动画倒计时部分 [self scaleActionWithBeginBlock:begin andSuccessBlock:success button:button]; return button; } // 动画倒计时部分 + (void)scaleActionWithBeginBlock:(CountdownBeginBlock)begin andSuccessBlock:(CountdownSuccessBlock)success button:(WZBCountDownButton *)button { if (!isAnimationing) { // 如果不在动画, 才走开始的代理和block if (begin) begin(button); if ([button.delegate respondsToSelector:@selector(countdownBegin:)]) [button.delegate countdownBegin:button]; } if (button.countDownType == WZBCountDownImage) { [self setAnimationImage:button]; } else { [self setAnimationNumber:button]; } } // 播放倒计时图片 + (void)setAnimationImage:(WZBCountDownButton *)button { if (button.images.count > 0) { isAnimationing = YES; [button setImage:[UIImage imageNamed:button.images.firstObject] forState:UIControlStateNormal]; [UIView animateWithDuration:1.0f animations:^{ button.transform = CGAffineTransformIdentity; button.alpha = 1; } completion:^(BOOL finished) { if (finished) { button.alpha = 0; button.transform = CGAffineTransformMakeScale(5, 5); if (button.images.count > 0) { [button.images removeObjectAtIndex:0]; [self scaleActionWithBeginBlock:button.countdownBeginBlock andSuccessBlock:button.countdownSuccessBlock button:button]; } } }]; } else { // 调用倒计时完成的代理和block if ([button.delegate respondsToSelector:@selector(countdownSuccess:)]) [button.delegate countdownSuccess:button]; if (button.countdownSuccessBlock) button.countdownSuccessBlock(button); [self hidden]; } }
简单解释下代码的实现原理:
调用这个方法,首先先判断当前是否正在播放倒计时,如果正在播放,直接return nil;
如果没有在播放,则创建一个UIButton,然后为button赋值(一些全局变量),如果是数字倒计时,那么为button赋值为初始的数字,然后再判断有没有结束语,如果有,则总倒计时增加一秒钟(为最后的结束语留一秒播放时间)。然后判断总数值是否大于0,如果不大于,则证明已经播放完了,然后调用代理和block,以及隐藏掉self。如果判断大于0,则开始开始循环播放动画,这里用的是UIView动画,每次动画执行1秒,动画执行结束,控制全局数值的number属性减一,重新开始循环上边步骤。
如果是倒计时图片,则开始走播放倒计时图片的方法,先判断外部传入的图片数组个数是否大于0,如果不大于,则证明已经倒计时结束了(或者使用者没有传入任何图片),然后调用代理和block,以及隐藏self。如果图片个数大于0,从图片数组中取出第一个图片为button赋值,然后开始动画,动画执行完,先把数组中的第一张图片移除掉,然后重新开始上边的步骤。知道执行结束为止。
此demo中其他可用的方法:
/** 设置文字颜色和字体大小 @param textColor 文字颜色(默认红色) @param textFont 字体大小(默认为20) */ + (void)setTextColor:(UIColor *)textColor textFont:(UIFont *)textFont; /** 设置文字颜色 @param textColor 文字颜色(默认红色) */ + (void)setTextColor:(UIColor *)textColor; /** 设置字体大小 @param textFont 字体大小(默认为20) */ + (void)setTextFont:(UIFont *)textFont; /** 全是默认值的play方法 */ + (instancetype)play; /** 隐藏 */ + (void)hidden; /** 初始化并开始播放 @param number 倒计时开始数字 @return WZBCountDownButton的实例 */ + (instancetype)playWithNumber:(NSInteger)number; /** 初始化并开始播放 @param number 倒计时开始数字 @param endTitle 倒计时结束时显示的字符 @return WZBCountDownButton的实例 */ + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle; /** 初始化并开始播放 @param number 倒计时开始数字 @param success 倒计时开始回调 @return WZBCountDownButton的实例 */ + (instancetype)playWithNumber:(NSInteger)number success:(CountdownSuccessBlock)success; /** 初始化并开始播放 @param number 倒计时开始数字 @param endTitle 倒计时结束时显示的字符 @param success 倒计时开始回调 @return WZBCountDownButton的实例 */ + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle success:(CountdownSuccessBlock)success; /** 初始化并开始播放 @param number 倒计时开始数字 @param endTitle 倒计时结束时显示的字符 @param begin 倒计时开始回调 @param success 倒计时完成回调 @return WZBCountDownButton的实例 */ + (instancetype)playWithNumber:(NSInteger)number endTitle:(NSString *)endTitle begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success; /** 初始化并开始播放 @param images 需要播放的图片 @param begin 倒计时开始回调 @param success 倒计时完成回调 @return WZBCountDownButton的实例 */ + (instancetype)playWithImages:(NSArray *)images begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success; /** 初始化并开始播放 @param images 需要播放的图片 @param duration 时间间隔(暂未实现) @param begin 倒计时开始回调 @param success 倒计时完成回调 @return WZBCountDownButton的实例 */ + (instancetype)playWithImages:(NSArray *)images duration:(NSTimeInterval)duration begin:(CountdownBeginBlock)begin success:(CountdownSuccessBlock)success; /** 绑定代理 */ + (void)addDelegate:(id)delegate; /** 倒计时完成时的block监听 */ + (void)addCountdownSuccessBlock:(CountdownSuccessBlock)success; /** 倒计时开始时的block监听 */ + (void)addCountdownBeginBlock:(CountdownBeginBlock)begin; /** 倒计时开始时和结束时的block监听 */ + (void)addCountdownBeginBlock:(CountdownBeginBlock)begin successBlock:(CountdownSuccessBlock)success;
这些方法的注视都比较清楚,就不再过多解释了。具体请下载demo。
以上介绍了基本的使用方法,在文件WZBCountDownButton.h中还有一些其他的一些操作,比如定制文字颜色、文字大小这些,比较简单,就不过多赘述了。我这个demo的功能很简单,但是封装的特别好,没有一个实例方法,全是直接拿类名可以直接调用的类方法,很值得学习一下。