我们经常会遇到按钮上进行倒计时的情况,比如获取验证码的时候。本文将讲解如何实现倒计时按钮。为了让大家清楚地知道本文的意图,先上图:
如图我使用了两种方法实现,一种是利用分类,另一种是利用继承。这边我只讲解继承,分类的核心代码基本同继承。如果你们想要直接看代码的话,请点击 这里 。
创建一个MJCountDownButton类继承自UIButton,.h中的代码如下
#import <UIKit/UIKit.h>
@class MJCountDownButton;
typedef void(^Completion)(MJCountDownButton *countDownButton);
@interface MJCountDownButton : UIButton
/**
* @author 王梦杰, 16-06-22 14:06:00
*
* 开始倒计时
*
* @param startTime 倒计时时间
* @param unitTitle 倒计时时间单位(如:s)
* @param completion 倒计时结束执行的Block
*/
- (void)countDownFromTime:(NSInteger)startTime unitTitle:(NSString *)unitTitle completion:(Completion)completion;
@end
.m中的代码如下:
#import "MJCountDownButton.h"
#import "UIImage+Color.h"
@implementation MJCountDownButton
- (void)countDownFromTime:(NSInteger)startTime unitTitle:(NSString *)unitTitle completion:(Completion)completion {
__weak typeof(self) weakSelf = self;
// 剩余的时间(必须用__block修饰,以便在block中使用)
__block NSInteger remainTime = startTime;
// 获取全局队列
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);
// 每隔1s钟执行一次
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
// 在queue中执行event_handler事件
dispatch_source_set_event_handler(timer, ^{
if (remainTime <= 0) { // 倒计时结束
dispatch_source_cancel(timer);
// 回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.enabled = YES;
completion(weakSelf);
});
} else {
NSString *timeStr = [NSString stringWithFormat:@"%ld", remainTime];
// 回到主线程更新UI
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf setTitle:[NSString stringWithFormat:@"%@%@",timeStr,unitTitle] forState:UIControlStateDisabled];
[weakSelf setBackgroundImage:[UIImage createImageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled];
weakSelf.enabled = NO;
});
remainTime--;
}
});
dispatch_resume(timer);
}
@end
这边还利用到一个UIImge的分类方法,该分类的作用是通过一个颜色对象返回一张图片对象,这个比较实用。
+ (UIImage *)createImageWithColor:(UIColor *)color {
// 画布大小
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
// 在当前画布上开启绘图上下文
UIGraphicsBeginImageContext(rect.size);
// 画笔
CGContextRef context = UIGraphicsGetCurrentContext();
// 设置画笔颜色
CGContextSetFillColorWithColor(context, [color CGColor]);
// 填充画布
CGContextFillRect(context, rect);
// 取得画布中的图片
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
// 结束绘图上下文
UIGraphicsEndImageContext();
return theImage;
}
文末再次附上源码地址:去下载。
顺手点个星的都是好同志。