iOS中倒计时按钮的实现

我们经常会遇到按钮上进行倒计时的情况,比如获取验证码的时候。本文将讲解如何实现倒计时按钮。为了让大家清楚地知道本文的意图,先上图:

countdown.gif

如图我使用了两种方法实现,一种是利用分类,另一种是利用继承。这边我只讲解继承,分类的核心代码基本同继承。如果你们想要直接看代码的话,请点击 这里

创建一个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;
}

文末再次附上源码地址:去下载
顺手点个星的都是好同志。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,415评论 25 708
  • 想飞上天 和太阳肩并肩 世界等着我去改变 想做的梦 从不怕别人看见 在这里我都能实现 大声欢...
    一个人干净利落_阅读 477评论 0 0
  • 01.论年轻 年轻就是好,即使一无所有也毫不畏惧。 02.论得失 失去该失去的,得到想得到的。 03.论同情 我接...
    1黄思源阅读 266评论 0 0
  • 你香染如玉,你诗画如墨,你是八旗中的贵族,你是千古一帝的宠臣。 你曾意气风发,你曾挥斥方遒,数百年如白驹过隙,你却...
    曜墨阅读 406评论 0 3
  • 走在路上,又有人在偷窥我,究竟是怎么回事?这事要回到三天以前。 “老婆,今晚吃什么?” “土豆焖牛腩吧”厨房传来老...
    乔之国阅读 367评论 0 0