iOS实现倒计时的两种方式
2017-05-11 本文已影响25人
郭小弟
`新手一枚,此文章只为记录程序人生的点点滴滴,希望大家能够提点一下,
谢谢!!
谢谢!!!
谢谢!!!
1.使用NSTimer实现倒计时
@interface ViewController ()
//按钮
@property (nonatomic ,strong)UIButton *btn;
//倒计时的总时间
@property (nonatomic ,assign)NSInteger secondsCountDown;
//定时器
@property (nonatomic ,strong)NSTimer *countDownTimer;;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.btn = [UIButton buttonWithType:UIButtonTypeCustom];
self.btn.frame = CGRectMake(100, 100, 100, 100);
self.btn.backgroundColor = [UIColor yellowColor];
[self.btn setTitle:@"获取验证码" forState:UIControlStateNormal];
//设置文字颜色
[self.btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
//添加点击事件
[self.btn addTarget:self action:@selector(startTime) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.btn];
}
//使用NSTimer实现倒计时功能
- (void)startTime
{
//设置倒计时总时长
self.secondsCountDown = 5;
/ * 创建一个timer , 并将它添加到当前线程的RunLoop
* 这是添加定时器的另一种方式,不过这个需要手动添加,而且当前线程是主线程
*/
// self.countDownTimer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(repeat:) userInfo:@{@"key":@"value"} repeats:true];
// [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
//这种方式定义一个定时器虽然很简单,但是有很多的弊端!如果现在在界面上加入一个scrollview的话滚动scrollView时,定时器会停止;原因:因为上面这种创建的定时器默认已经添加到当前的runLoop中了,当前的runloop就是主线程,主线程的runloop默认是开启的,程序默认也只开启这一个runloop,所以会阻塞主线程,造成定时器停止
self.countDownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startTimeNSTimer) userInfo:nil repeats:YES];
[self.btn setTitle:[NSString stringWithFormat:@"%ld秒后重新发送",(long)self.secondsCountDown] forState:UIControlStateNormal];
}
//使用NSTimer实现倒计时
- (void)startTimeNSTimer
{
self.secondsCountDown -- ;
self.btn.userInteractionEnabled = NO;
[self.btn setTitle:[NSString stringWithFormat:@"%ld秒后重新发送",(long)self.secondsCountDown] forState:UIControlStateNormal];
if (self.secondsCountDown == 0) {
[self.countDownTimer invalidate];
self.btn.userInteractionEnabled = YES;
[self.btn setTitle:@"重新发送验证码" forState:UIControlStateNormal];
}
}
2.使用GCD实现倒计时
- (void)startTimeGCD
{
//在block内部不可以修改外部变量,需要添加__block进行修饰
//设置倒计时总时长
__block int timeout=10;
//创建队列(全局并发队列)
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); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){
//倒计时结束,关闭
dispatch_source_cancel(_timer);
//回到主线程更新UI
dispatch_async(dispatch_get_main_queue(), ^{
//设置界面的按钮显示 根据自己需求设置
[self.btn setTitle:@"发送验证码" forState:UIControlStateNormal];
self.btn.userInteractionEnabled = YES;
});
}else{
int seconds = timeout % 60;
NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds];
dispatch_async(dispatch_get_main_queue(), ^{
//设置界面的按钮显示 根据自己需求设置
//NSLog(@"____%@",strTime);
// [UIView beginAnimations:nil context:nil];
// [UIView setAnimationDuration:1];
[self.btn setTitle:[NSString stringWithFormat:@"%@秒后重新发送",strTime] forState:UIControlStateNormal];
// [UIView commitAnimations];
self.btn.userInteractionEnabled = NO;
});
timeout--;
}
});
dispatch_resume(_timer);
}