当我们使用手机号码注册或登录时,很多时候需要用到获取验证码功能,前几天写了通过Mob第三方获取验证码功能,今天写一些细节,就是点击获取验证码按钮后,为了防止用户频繁获取,限定60秒之内只能获取一次,此时,就需要用到倒计时功能;
原理是让验证码按钮在这60秒之内,点击事件失效。
效果如下:
目前流行的倒计时方法有两种:
一种是通过NSTimer计时器实现;
二是通过GCD实现。
方式 一 :NSTimer
@interface ViewController ()
// 用于倒计时的数字
@property (nonatomic ,assign) NSInteger count;
// 创建一个NSTimer对象
@property (nonatomic ,strong) NSTimer *timer;
// 获取验证码按钮
@property (weak, nonatomic) IBOutlet UIButton *getCodeButton;
@end
- (void)viewDidLoad {
[super viewDidLoad];
[self.getCodeButton addTarget:self action:@selector(getCodeAction:) forControlEvents:UIControlEventTouchUpInside];
// Do any additional setup after loading the view, typically from a nib.
}
/**
* 利用NSTimer实现倒计时
*/
#pragma mark ----------利用NSTimer实现倒计时----------
- (IBAction)getCodeAction:(UIButton *)sender {
//为倒计时时间赋初始值
self.count = 20;
//初始化计时器
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
//设置按钮点击后,改变title的内容
[self.getCodeButton setTitle:[NSString stringWithFormat:@"%ld秒后重新发送",self.count] forState:UIControlStateNormal];
}
/**
* 计时器需要定时执行的动作
*/
-(void)timerAction{
//让倒计时时间减少,间隔为1
self.count -- ;
//更新按钮title的内容
[self.getCodeButton setTitle:[NSString stringWithFormat:@"%ld秒后重新发送",self.count] forState:UIControlStateNormal];
//停止按钮的交互
self.getCodeButton.userInteractionEnabled = NO;
//当倒计时时间结束时,销毁掉计时器,恢复按钮的交互,同时也更新按钮的title
if (self.count == 0) {
[self.timer invalidate];
self.getCodeButton.userInteractionEnabled = YES;
[self.getCodeButton setTitle:@"重新发送" forState:UIControlStateNormal];
}
}
方式 二 :GCD方式
- (void)viewDidLoad {
[super viewDidLoad];
[self.getCodeButton addTarget:self action:@selector(startTime) forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark ----------利用GCD实现倒计时----------
-(void)startTime{
__block int timeout=30; //倒计时时间
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);
dispatch_async(dispatch_get_main_queue(), ^{
//设置界面的按钮显示 根据自己需求设置
[self.getCodeButton setTitle:@"发送验证码" forState:UIControlStateNormal];
self.getCodeButton.userInteractionEnabled = YES;
});
}else{
// int minutes = timeout / 60;
int seconds = timeout % 60;
NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds];
dispatch_async(dispatch_get_main_queue(), ^{
//设置界面的按钮显示 根据自己需求设置
[self.getCodeButton setTitle:[NSString stringWithFormat:@"%@秒后重新发送",strTime] forState:UIControlStateNormal];
self.getCodeButton.userInteractionEnabled = NO;
});
timeout--;
}
});
dispatch_resume(timer);
}
总结:在倒计时过程中,按钮上的字是一闪一闪的,每秒闪烁一次,折腾了很久,没找到原因,最后请教了一位朋友,原因就一个字——坑
解决办法:将UIButton的类型由system改为custom
最后上张图: