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

上一篇下一篇

猜你喜欢

热点阅读