倒計時是現在項目中很常用到的一個模塊, 尤其是在跟電商項目掛鉤的項目中.
之前在使用NSTimer時發(fā)現
如果NSTimer執(zhí)行過程中由于某種原因被延遲童番,會略過本該在延遲期間需要執(zhí)行的方法倔幼。
解決方案是使用GCD定時器。
/**
* 倒計時工具
*
* @param time 倒計時時間
* @param blockYes 倒計時結束 設置UI
* @param blockNo 倒計時進行中 設置UI
*/
+ (void)verificationCode:(long long)time blockYes:(void(^)())blockYes blockNo:(void(^)(id time))blockNo
{
??__block long long timeout = time; //倒計時時間
??dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
??dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
??dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒執(zhí)行
??dispatch_source_set_event_handler(_timer, ^{
????if(timeout<=0){ //倒計時結束衅码,關閉
??????dispatch_source_cancel(_timer);
??????dispatch_async(dispatch_get_main_queue(), ^{
????????//設置界面的按鈕顯示 根據自己需求設置
????????blockYes();
??????});
????}else{
??????// int minutes = timeout / 60;
??????int seconds = timeout % 60;
??????NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds];
??????dispatch_async(dispatch_get_main_queue(), ^{
????????//設置界面的按鈕顯示 根據自己需求設置
????????blockNo(strTime);
??????});
????timeout--;
????}
??});
??dispatch_resume(_timer);
}
這樣寫的話能夠保證倒計時時間更準確.
既然是倒計時搶購, 光有倒計時是不夠的. 還需要有剩余時間的顯示, 你所得到的是秒數, 還需要把秒數轉化為()天()時()分()秒.
- (void)getDetailTimeWithTimestamp:(NSInteger)timestamp
{
??NSInteger ms = timestamp;
??NSInteger ss = 1;
??NSInteger mi = ss * 60;
??NSInteger hh = mi * 60;
??NSInteger dd = hh * 24;
??// 剩余的
??NSInteger day = ms / dd;// 天
??NSInteger hour = (ms - day * dd) / hh;// 時
??NSInteger minute = (ms - day * dd - hour * hh) / mi;// 分
??NSInteger second = (ms - day * dd - hour * hh - minute * mi) / ss;// 秒
??NSLog(@"%zd日:%zd時:%zd分:%zd秒",day,hour,minute,second);
??self.limitTimeLabel.text = [NSString stringWithFormat:@"%zd天%zd:%zd:%zd",day,hour,minute,second];
}
這樣, 一個倒計時搶購就完成了.
log.png
Log還是比較準的.