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

2018-04-12  本文已影响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 @"重新发送验证码";
   }];
}
上一篇 下一篇

猜你喜欢

热点阅读