美文网首页
UIButton倒计时

UIButton倒计时

作者: 喵喵粉 | 来源:发表于2020-04-21 18:20 被阅读0次
  • oc

用法

[[BaseRequest shared] requestWithUrl:@"" param:pram success:^(id  _Nonnull result) {    
    [NSObject extBtnCountHandlerBlock:^(int times) {
        NSString *strTime = [NSString stringWithFormat:@"%d秒重发",times];
        [sender setTitle:strTime forState:UIControlStateNormal];
    } finishBlock:^{
        [sender setEnabled:YES];
        [sender setTitle:@"重发验证码" forState:UIControlStateNormal];
    }];
} failure:^(id  _Nonnull error) {
    sender.enabled = YES;
}]

NSObject分类
.h

@interface NSObject (SMSTimer)

/** 倒计时
 - (IBAction)getCode:(UIButton *)sender {
     NSDictionary *pram = @{@"content": @"abc"};
     sender.enabled = NO;
     UserManager *um = [UserManager shared];
     [[BaseRequest shared] requestWithUrl:__FEEDBACKADD param:pram token:um.token success:^(id  _Nonnull result) {
         [MBProgressHUD showMessage:@"感谢您的反馈,我们会尽快核实处理"];
         
         [NSObject extBtnCountHandlerBlock:^(int times) {
             NSString *strTime = [NSString stringWithFormat:@"%d秒重发",times];
             [sender setTitle:strTime forState:UIControlStateNormal];
         } finishBlock:^{
             [sender setEnabled:YES];
             [sender setTitle:@"重发验证码" forState:UIControlStateNormal];
         }];
     } failure:^(id  _Nonnull error) {
         sender.enabled = YES;
         [MBProgressHUD showMessage:error];
     }];
}
 */
+ (void)extBtnCountdown:(int)seconds
           handlerBlock:(void (^)(int times))handlerBlock
            finishBlock:(void (^)(void))finishBlock;
+ (void)extBtnCountHandlerBlock:(void (^)(int times))handlerBlock
                    finishBlock:(void (^)(void))finishBlock;

@end

.m

#import "NSObject+SMSTimer.h"

@implementation NSObject (SMSTimer)

+ (void)extBtnCountHandlerBlock:(void (^)(int times))handlerBlock
                    finishBlock:(void (^)(void))finishBlock {
    [self extBtnCountdown:10 handlerBlock:handlerBlock finishBlock:finishBlock];
}
+ (void)extBtnCountdown:(int)seconds
           handlerBlock:(void (^)(int times))handlerBlock
            finishBlock:(void (^)(void))finishBlock {
    __block int timeout = seconds-1; //倒计时时间
    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(), ^{
//                handlerBlock(@"重发验证码");
                finishBlock();
            });
        } else {
            // int minutes = timeout / seconds;
            int second = timeout % seconds;
            NSString *strTime = [NSString stringWithFormat:@"%d秒重发",second];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                handlerBlock(second);
            });
            timeout--;
        }
    });
    dispatch_resume(_timer);
}

@end
  • swift

用法

///当定时器每隔一秒更改标题时,会有闪烁现象,将UIButtonType.System更改为UIButtonType.Custom即可
///倒计时
TimeCountdown.extStartCount(seconds: 60, process: { (time) in
    self.btnSms.setTitle("重发(\(time)s)", for: .normal)
    self.btnSms.isEnabled = false
}) {
    self.btnSms.setTitle("获取验证码", for: .normal)
    self.btnSms.isEnabled = true
}

///请求成功 停止计时
TimeCountdown.extStop {
    self.btnSms.setTitle("获取验证码", for: .normal)
    self.btnSms.isEnabled = true
}
typealias SuccessBlock = () -> ()
typealias ProcessBlock = (Int) -> ()

class TimeCountdown {
    
    static var timer: DispatchSourceTimer?
    
    ///当定时器每隔一秒更改标题时,会有闪烁现象,将UIButtonType.System更改为UIButtonType.Custom即可
    static func extStartCount(seconds: TimeInterval, process: @escaping ProcessBlock, finish: @escaping SuccessBlock) {
        
        ///获取全局队列
        let queue = DispatchQueue.global(qos: DispatchQoS.QoSClass.default)
        
        ///创建一个定时器,并将定时器的任务交给全局队列执行(并行,不会造成主线程阻塞)
        timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
        
        let startTime = DispatchTime.now()
        let endTime = CACurrentMediaTime() + seconds
        
        ///每秒执行一次
        timer?.schedule(deadline: startTime, repeating: DispatchTimeInterval.seconds(1))
        timer?.setEventHandler {
            
            ///更新倒计时
            let interval = Int(endTime-CACurrentMediaTime())
            if interval > 0 {
                DispatchQueue.main.async {
                    process(interval)
                }
            }
            ///倒计时结束,关闭
            else {
                timer?.cancel()
                timer = nil

                DispatchQueue.main.async {
                    finish()
                }
            }
        }
        timer?.resume()
    }
    
    ///主动停止
    static func extStop(_ finish: @escaping SuccessBlock) {
        timer?.cancel()
        timer = nil
        finish()
    }
}

相关文章

网友评论

      本文标题:UIButton倒计时

      本文链接:https://www.haomeiwen.com/subject/paypihtx.html