问题描述:
因项目需要,需要实现一个倒计时功能,实时刷新UI。如果倒计时结束后,为做出相应的操作,则会有不同的提示或者页面转换。
倒计时的实现有两种:
- 使用NSTimer定时器来倒计时
- 使用GCD来倒计时(用GCD这个写有一个好处,跳页不会清零, 跳页清零会出现倒计时错误的)
这里给出倒计时的部分,主要采用GCD方式来编写的。
实现步骤
Step1. 计算截止时间与当前时间差
Step2. 用GCD倒计时 给秒通过递减过后的秒数,重新计算数值,并输出显示, 递减时间差 倒计时-1
在timeController.h文件中:
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface timeController : NSObject
+ (void)initWithGCD:(int)timeValue beginState:(void (^)(void))begin endState:(void (^)(int seconds))end;
+ (void)cancelTimer;
@end
NS_ASSUME_NONNULL_END
在timeController.m文件中:
#import "timeController.h"
@implementation timeController
dispatch_source_t timer=nil;
+ (void)initWithGCD:(int)timeValue beginState:(void (^)(void))begin endState:(void (^)(int seconds))end {
__block NSInteger time = timeValue;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//设置倒计时为1秒一次计时
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{
if (time < 0) {dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
begin();
});
} else {
int seconds = time % 60;
dispatch_async(dispatch_get_main_queue(), ^{
end(seconds);
});
time--;
}
});
dispatch_resume(timer);
}
+ (void)cancelTimer{
if(timer!=nil){
dispatch_source_cancel(timer);
}
}
@end
调用:
#import "ViewController.h"
#import "timeController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *timeCounter;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.timeCounter.frame = CGRectMake(CGRectGetMidX(self.view.bounds) - 80, CGRectGetMidY(self.view.bounds)-50 -(CGRectGetMidY(self.view.frame)-50)/2, 160, 50);
self.timeCounter.textColor = [UIColor redColor];
[self.view addSubview:self.timeCounter];
[self initCaptchaTimer];
// Do any additional setup after loading the view.
}
-(void) initCaptchaTimer{
[timeController cancelTimer];
[timeController initWithGCD:10 beginState:^{
//倒计时结束的操作
NSLog(@"结束");
} endState:^(int seconds) {
//倒计时过程中的操作,可以刷新UI
self.timeCounter.text =[NSString stringWithFormat:@"剩余%d s",seconds];
}];
}
@end
这样就可以实现一个倒计时的功能了。