iOS 倒计时控件EBCountDownButton

823 阅读1分钟

大部分app注册、短信登录都会有填写手机号码或者邮箱获取验证码的步骤,刚好自己项目中也需要用到,就基于UIButton封装了一个小控件。

github地址:https://github.com/woheduole/EBCountDownButton

效果图

countDownButton.gif

调用方式

    EBCountDownButton *countDownButton = [[EBCountDownButton alloc] initWithFrame:CGRectMake(100, 100, 140, 40)];
    [countDownButton setTitle:@"获取验证码" forState:UIControlStateNormal];
    [countDownButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    countDownButton.backgroundColor = [UIColor colorWithRed:40/255.0 green:207/255.0 blue:155/255.0 alpha:1];
    [countDownButton addTarget:self action:@selector(sendVerificationCode:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:countDownButton];
- (void)sendVerificationCode:(EBCountDownButton*)countDownButton {
    [countDownButton countDownWithDuration:5 completion:^(BOOL finished) {
        NSLog(@"finished");
    }];
}

代码结构

  • EBCountDownButton.h
typedef void (^EBCountDownButtonBlock)(BOOL finished);

@interface EBCountDownButton : UIButton
- (void)countDownWithDuration:(NSTimeInterval)duration completion:(EBCountDownButtonBlock)completion;
@end
  • EBCountDownButton.m
- (void)countDownWithDuration:(NSTimeInterval)duration completion:(EBCountDownButtonBlock)completion {
    self.enabled = NO;
    _duration = duration;
    _completion = completion;
    [self setTitle:[NSString stringWithFormat:@"%ld%@"
                    , (long)duration
                    , kEBCountDownButtonUnitTime] forState:UIControlStateDisabled];
    [self setBackgroundImage:[self createImageWithColor:[UIColor lightGrayColor]] forState:UIControlStateDisabled];
    [self setupTimer];
}

小技巧:注意在设置self.enabled = NO之后,这时候title的state就应该是UIControlStateDisabled,这样在倒计时结束之后设置self.enabled=YES的时候,button的title会自动变回倒计时之前的title的值。

- (void)setupTimer {
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countDown) userInfo:nil repeats:YES];
    _timer = timer;
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

scheduledTimerWithTimeInterval会自动执行,并且自动加入当前线程的Run Loop中其mode为:NSDefaultRunLoopMode,当既有定时器的地方又存在UIScrollview、UITableview、UITextview、UICollectionView这些可以滚动的控件,他们在滚动的时候mode将会被切换至UITrackingRunLoopMode模式下,这时候如果定时器被添加在NSDefaultRunLoopMode模式下,那么定时器会被暂停,停止滚动定时器才能恢复。如果想要他们互相不干扰,就必须将定时器添加在NSRunLoopCommonModes模式下,因为这两个模式NSDefaultRunLoopMode 和 UITrackingRunLoopMode都被标记为Common Modes了。

github地址:https://github.com/woheduole/EBCountDownButton