iOS-获取验证码中的倒计时功能

当我们使用手机号码注册或登录时,很多时候需要用到获取验证码功能,前几天写了通过Mob第三方获取验证码功能,今天写一些细节,就是点击获取验证码按钮后,为了防止用户频繁获取,限定60秒之内只能获取一次,此时,就需要用到倒计时功能;
原理是让验证码按钮在这60秒之内,点击事件失效。

效果如下:
iOS-获取验证码中的倒计时功能_第1张图片

目前流行的倒计时方法有两种:
一种是通过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

最后上张图:
iOS-获取验证码中的倒计时功能_第2张图片

你可能感兴趣的:(验证码,倒计时,gcd,NSTimer)