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 @"重新发送验证码";
}];
}