概述
詳細
一、准備工作
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<WZBCountDownButtonDelegate>)delegate; /** 倒計時完成時的block監聽 */ + (void)addCountdownSuccessBlock:(CountdownSuccessBlock)success; /** 倒計時開始時的block監聽 */ + (void)addCountdownBeginBlock:(CountdownBeginBlock)begin; /** 倒計時開始時和結束時的block監聽 */ + (void)addCountdownBeginBlock:(CountdownBeginBlock)begin successBlock:(CountdownSuccessBlock)success;
這些方法的注視都比較清楚,就不再過多解釋了。具體請下載demo。
四、其他
以上介紹了基本的使用方法,在文件WZBCountDownButton.h中還有一些其他的一些操作,比如定制文字顏色、文字大小這些,比較簡單,就不過多贅述了。我這個demo的功能很簡單,但是封裝的特別好,沒有一個實例方法,全是直接拿類名可以直接調用的類方法,很值得學習一下。
