美文网首页
iOS开发 - 短信验证码倒计时按钮

iOS开发 - 短信验证码倒计时按钮

作者: 阿唯不知道 | 来源:发表于2018-04-12 12:57 被阅读0次

    你没看错,只需调用一个方法即可实现短信验证码倒计时功能


    效果图展示.png

    首先创建一个继承于UIButton的倒计时按钮

    创建一个继承于UIButton的倒计时按钮

    #import "YSCountDownButton.h 文件"

    /**
     * 倒计时按钮 - 短信验证码获取
     */
    
    #import <UIKit/UIKit.h>
    
    @class YSCountDownButton;
    
    typedef NSString* (^CountDownChanging)(YSCountDownButton *countDownButton, NSInteger second);
    typedef NSString* (^CountDownFinished)(YSCountDownButton *countDownButton, NSInteger second);
    typedef void (^TouchedCountDownButtonHandler)(YSCountDownButton *countDownButton,NSInteger tag);
    
    @interface YSCountDownButton : UIButton
    
    // 倒计时按钮点击回调
    - (void)countDownButtonHandler:(TouchedCountDownButtonHandler)touchedCountDownButtonHandler;
    
    /**
      开始倒计时 -> 计时器改变 -> 结束倒计时
    
     @param second 传入需要倒计时的秒数
     @param countDownChanging 倒计时改变回调
     @param countDownFinished 倒计时结束回调
     */
    - (void)startCountDownWithSecond:(NSInteger)second
                   countDownChanging:(CountDownChanging)countDownChanging
                   countDownFinished:(CountDownFinished)countDownFinished;
    @end
    
    

    #import "YSCountDownButton.m 文件"

    #import "YSCountDownButton.h"
    
    @interface YSCountDownButton()
    {
        NSTimer         *_timer;        //计时器
        NSDate          *_startDate;    //开始时间
        NSInteger       _second;        //剩余秒数
        NSInteger      _totalSecond;   //总秒数
        
        CountDownChanging               _countDownChanging;
        CountDownFinished               _countDownFinished;
        TouchedCountDownButtonHandler   _touchedCountDownButtonHandler;
    }
    @end
    
    @implementation YSCountDownButton
    
    #pragma mark - * * * * * 给按钮添加点击事件 * * * * *
    
    - (void)countDownButtonHandler:(TouchedCountDownButtonHandler)touchedCountDownButtonHandler
    {
        _touchedCountDownButtonHandler = [touchedCountDownButtonHandler copy];
        [self addTarget:self action:@selector(touched:) forControlEvents:UIControlEventTouchUpInside];
    }
    
    - (void)touched:(YSCountDownButton *)sender
    {
        if (_touchedCountDownButtonHandler) {
            dispatch_async(dispatch_get_main_queue(), ^{
                _touchedCountDownButtonHandler(sender,sender.tag);
            });
        }
    }
    
    #pragma mark - * * * * * 开始倒计时 * * * * *
    
    - (void)startCountDownWithSecond:(NSInteger)totalSecond countDownChanging:(CountDownChanging)countDownChanging countDownFinished:(CountDownFinished)countDownFinished
    {
        self.enabled = NO;
        _totalSecond = totalSecond;
        _second = totalSecond;
        
        _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerStart:) userInfo:nil repeats:YES];
        _startDate = [NSDate date];
        _timer.fireDate = [NSDate distantPast];
        [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
        if (countDownChanging) {
            _countDownChanging = [countDownChanging copy];
        }
        if (countDownFinished) {
            _countDownFinished = [countDownFinished copy];
        }
    }
    
    #pragma mark - * * * * * private * * * * *
    
    // 停止倒计时
    - (void)stopCountDown
    {
        if (!_timer || ![_timer respondsToSelector:@selector(isValid)] || ![_timer isValid]) {
            return;
        }
        [_timer invalidate];
        _second = _totalSecond;
        if (_countDownFinished) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSString *title = _countDownFinished(self,_totalSecond);
                [self setTitle:title forState:UIControlStateNormal];
                [self setTitle:title forState:UIControlStateDisabled];
            });
        }else {
            [self setTitle:@"重新发送验证码" forState:UIControlStateNormal];
            [self setTitle:@"重新发送验证码" forState:UIControlStateDisabled];
        }
        self.enabled = YES;
    }
    
    // 计时器开始
    - (void)timerStart:(NSTimer *)theTimer
    {
        double deltaTime = [[NSDate date] timeIntervalSinceDate:_startDate];
        
        _second = _totalSecond - (NSInteger)(deltaTime+0.5) ;
        
        if (_second < 1) {
            [self stopCountDown];
        }else {
            if (_countDownChanging) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSString *title = _countDownChanging(self,_second);
                    [self setTitle:title forState:UIControlStateNormal];
                    [self setTitle:title forState:UIControlStateDisabled];
                });
            }else {
                NSString *title = [NSString stringWithFormat:@"%zd秒再获取",_second];
                [self setTitle:title forState:UIControlStateNormal];
                [self setTitle:title forState:UIControlStateDisabled];
                
            }
        }
    }
    
    @end
    

    调用方式(引用YSCountDownButton.h后)

    #pragma mark - * * * * * 纯代码展示 * * * * *
    // 按钮添加到界面
    YSCountDownButton *btn = [YSCountDownButton buttonWithType:UIButtonTypeCustom];
    [btn setTitle:@"纯代码:获取验证码" forState:UIControlStateNormal];
    [btn setTitleColor:kRandomColor forState:UIControlStateNormal];
    btn.borderWidth = 1;
    btn.borderColor = btn.currentTitleColor;
    [self.view addSubview:btn];
    [btn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(self.view.mas_centerY).offset(-100);
        make.centerX.mas_equalTo(self.view.mas_centerX);
        make.size.mas_equalTo(CGSizeMake(200, 50));
    }];
    
    // 先给按钮添加回调,然后再开始调用倒计时方法
    [btn countDownButtonHandler:^(YSCountDownButton *countDownButton, NSInteger tag) {
        // 点击按钮后开始倒计时
        [countDownButton startCountDownWithSecond:10 countDownChanging:^NSString *(YSCountDownButton *countDownButton, NSInteger second) {
            NSString *title = [NSString stringWithFormat:@"%zd 秒再获取",second];
            return title;
        } countDownFinished:^NSString *(YSCountDownButton *countDownButton, NSInteger second) {
            return @"重新发送验证码";
        }];
    }];
    
    #pragma mark - * * * * * xib拖拽展示 * * * * *
    /**
    * ⚠️注意:xib拖拽时需要关联Class:YSCountDownButton
    */
    - (IBAction)xibBtnAction:(YSCountDownButton *)sender {
       
       // 点击按钮后开始倒计时
       [sender startCountDownWithSecond:10 countDownChanging:^NSString *(YSCountDownButton *countDownButton, NSInteger second) {
           NSString *title = [NSString stringWithFormat:@"%zd 秒再获取",second];
           return title;
       } countDownFinished:^NSString *(YSCountDownButton *countDownButton, NSInteger second) {
           return @"重新发送验证码";
       }];
    }
    

    相关文章

      网友评论

          本文标题:iOS开发 - 短信验证码倒计时按钮

          本文链接:https://www.haomeiwen.com/subject/jhuxkftx.html