iOS 分类之按钮倒计时UIButton+CountDown

这篇博客介绍了如何在iOS中为UIButton添加倒计时功能,包括使用UIButton+CountDown类别进行扩展,并参考了关于NSTimer在后台运行及锁屏时的处理策略。

UIButton+CountDown.h


#import <UIKit/UIKit.h>

typedef void(^RunBlock)(UIButton *button, NSInteger totalTime, NSInteger leftTime);
typedef void(^EndBlock)(UIButton *button);

@interface UIButton (CountDown)

/**
 *  倒计时按钮
 *
 *  @param duration 总时间
 *  @param runBlock 倒计时期间回调
 *  @param endBlock 倒计时结束回调
 */
- (void)startWithDuration:(NSInteger)duration
                  running:(RunBlock)runBlock
                 finished:(EndBlock)endBlock;
@end

UIButton+CountDown.m


#import "UIButton+CountDown.h"

@implementation UIButton (CountDown)

- (void)startWithDuration:(NSInteger)duration running:(RunBlock)runBlock finished:(EndBlock)endBlock
{
    __block NSInteger timeOut = duration;
    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);

    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(_timer, ^{

        if (timeOut <= 0) {

            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                endBlock(self);
            });
        } else {

            int allTime = (int)duration + 1;
            int seconds = timeOut % allTime;
            dispatch_async(dispatch_get_main_queue(), ^{
                runBlock(self, duration, seconds);
            });
            timeOut--;
        }
    });
    dispatch_resume(_timer);
}

@end

Tips: 

倒计时除了GCD还可以使用NSTimer实现,但是有一个问题,也是我的测试反馈的:

应用进入后台一段时间,倒计时不工作,它只会从上一次消失的时间开始继续工作。

朋友们可以搜索“NSTimer 进入后台”,网上是说:进入后台,定时器线程被挂起,进入前台才继续工作。

所以,如果你有这方面的需求,而且是在不影响其他工作(比如音视频播放),可以在 AppDelegate.m 中添加如下代码:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    __block UIBackgroundTaskIdentifier backgroundTask;

    backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (backgroundTask != UIBackgroundTaskInvalid)
            {
                backgroundTask = UIBackgroundTaskInvalid;
            }
        });
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (backgroundTask != UIBackgroundTaskInvalid)
            {
                backgroundTask = UIBackgroundTaskInvalid;
            }
        });
    });
}

参考文章:

iOS程序进入后台后仍运行定时器NSTimer

NSTimer 锁屏以及进入后台不调用的解决方案

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值