美文网首页
OC:倒计时进阶

OC:倒计时进阶

作者: 春暖花已开 | 来源:发表于2018-11-07 18:51 被阅读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
    
    

    相关文章

      网友评论

          本文标题:OC:倒计时进阶

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