NSTimer方式
@interface TimerButton ()
@property (nonatomic, strong, readwrite) NSTimer *timer;
@property (assign, nonatomic) NSTimeInterval durationToValidity;
@property (strong, nonatomic) UIView *lineView;
@end
@implementation TimerButton
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.titleLabel.font = [UIFont systemFontOfSize:14];
self.enabled = YES;
_lineView = [[UIView alloc] initWithFrame:CGRectMake(-10, 5, 0.5, CGRectGetHeight(frame) - 2*5)];
_lineView.backgroundColor = [UIColor redColor];
[self addSubview:_lineView];
}
return self;
}
- (void)setEnabled:(BOOL)enabled{
[super setEnabled:enabled];
UIColor *foreColor = enabled ? [UIColor redColor] : [UIColor greenColor];
[self setTitleColor:foreColor forState:UIControlStateNormal];
if (enabled) {
[self setTitle:@"发送验证码" forState:UIControlStateNormal];
}else if ([self.titleLabel.text isEqualToString:@"发送验证码"]){
[self setTitle:@"正在发送..." forState:UIControlStateNormal];
}
}
- (void)startUpTimer{
_durationToValidity = 60;
if (self.isEnabled) {
self.enabled = NO;
}
[self setTitle:[NSString stringWithFormat:@"%.0f 秒", _durationToValidity] forState:UIControlStateNormal];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(redrawTimer:)
userInfo:nil
repeats:YES];
}
- (void)invalidateTimer{
if (!self.isEnabled) {
self.enabled = YES;
}
[self.timer invalidate];
self.timer = nil;
}
- (void)redrawTimer:(NSTimer *)timer {
_durationToValidity--;
if (_durationToValidity > 0) {
self.titleLabel.text = [NSString stringWithFormat:@"%.0f 秒", _durationToValidity];//防止 button_title 闪烁
[self setTitle:[NSString stringWithFormat:@"%.0f 秒", _durationToValidity] forState:UIControlStateNormal];
}else{
[self invalidateTimer];
}
}
GCD方式
@implementation TimerGCD
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.titleLabel.font = [UIFont systemFontOfSize:14];
self.enabled = YES;
}
return self;
}
- (void)startTime {
NSInteger time = 59;
__block NSInteger timeout = time; //倒计时时间
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(), ^{
self.enabled = YES;
});
} else {
NSInteger seconds = timeout % 60;
NSString *strTime = [NSString stringWithFormat:@"%.2ld", (long)seconds];
dispatch_async(dispatch_get_main_queue(), ^{
[self setTitle:[NSString stringWithFormat:@"重发(%@)",strTime] forState:UIControlStateNormal];
// iOS 7
[self setTitle:[NSString stringWithFormat:@"重发(%@)",strTime] forState:UIControlStateDisabled];
self.enabled = NO;
});
timeout--;
}
});
dispatch_resume(_timer);
}
- (void)setEnabled:(BOOL)enabled{
[super setEnabled:enabled];
UIColor *foreColor = enabled ? [UIColor redColor] : [UIColor greenColor];
[self setTitleColor:foreColor forState:UIControlStateNormal];
if (enabled) {
[self setTitle:@"发送验证码" forState:UIControlStateNormal];
}else if ([self.titleLabel.text isEqualToString:@"发送验证码"]){
[self setTitle:@"正在发送..." forState:UIControlStateNormal];
}
}