OC:倒计时进阶
2018-11-07 本文已影响40人
春暖花已开
更新日志:2018-11-20 修复没有点击,退到后台,重新进入前台,触发倒计时的问题。
#import <UIKit/UIKit.h>
@interface SMTCountButton : UIButton
// 开始倒计时
- (void)timeDown;
// button重置为初始状态
- (void)resetButtonStatus;
@end
#import "SMTCountButton.h"
#import "NSTimer+SmartUtils.h"
@interface SMTCountButton ()
@property (nonatomic, strong) NSDate *endDate;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSInteger wholeSeconds;
@property (nonatomic, assign) BOOL hasClicked;
@end
@implementation SMTCountButton
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self configure];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self configure];
}
return self;
}
#pragma mark - Public Methods
- (void)timeDown {
self.hasClicked = YES;
[self resetWholeSeconds];
[self.timer sm_resume];
}
#pragma mark - Private Methods
- (void)configure {
[self resetWholeSeconds];
self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerCountDown) userInfo:nil repeats:YES useProxy:YES runloopMode:NSRunLoopCommonModes];
[self.timer sm_pause];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActiveSelector) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActiveSelector) name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)applicationWillResignActiveSelector {
[self.timer sm_pause];
self.endDate = [NSDate dateWithTimeIntervalSinceNow:self.wholeSeconds];
}
- (void)applicationDidBecomeActiveSelector {
if (self.hasClicked) {
self.wholeSeconds = (NSInteger)[self.endDate timeIntervalSinceDate:[NSDate date]];
[self.timer sm_resume];
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)timerCountDown {
if (self.wholeSeconds > 0) {
[self setTitle:[NSString stringWithFormat:@"%ld秒后重试", (long)self.wholeSeconds] forState:UIControlStateNormal];
self.enabled = NO;
self.wholeSeconds--;
} else {
[self resetButtonStatus];
}
}
- (void)resetWholeSeconds {
self.wholeSeconds = 60;
}
- (void)resetButtonStatus {
self.hasClicked = NO;
[self.timer sm_pause];
[self resetWholeSeconds];
[self setTitle:@"获取验证码" forState:UIControlStateNormal];
self.enabled = YES;
}
@end
题外话
用块
来打破NSTimer的引用循环:
#import "NSTimer+MZExtension.h"
@implementation NSTimer (MZExtension)
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti block:(void(^)(void))block repeats:(BOOL)yesOrNo {
return [NSTimer timerWithTimeInterval:ti target:self selector:@selector(blockInvoke:) userInfo:[block copy] repeats:yesOrNo];
}
+ (void)blockInvoke:(NSTimer *)timer {
void(^block)(void) = timer.userInfo;
!block ?: block();
}
@end