美文网首页
iOS定时器——倒计时(天、时、分、秒)

iOS定时器——倒计时(天、时、分、秒)

作者: 文子飞_ | 来源:发表于2021-03-12 17:09 被阅读0次
    倒计时(天、时、分、秒)
    @implementation HoursCountDown {
        BOOL _valid;
        dispatch_source_t _timer;
        dispatch_semaphore_t _lock;
    }
    
    + (instancetype)scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval
                                           handler:(void(^)(NSString *timeString))handlerBlcok
    {
        return [[self alloc] initWithTimeInterval:timeInterval handler:handlerBlcok];
    }
    
    - (instancetype)initWithTimeInterval:(NSTimeInterval)timeInterval handler:(void(^)(NSString *timeString))handlerBlcok
    {
        self = [super init];
        if (self) {
            [self dispatch_source_set_timer:timeInterval handler:handlerBlcok];
        }
        return self;
    }
    
    /// 倒计时
    /// @param timeInterval 倒计时剩余时间(endTimeInterval-beginTimeInterval,两个时间戳相差)
    /// @param handlerBlcok 倒计时剩余时间(天、时、分、秒)
    - (void)dispatch_source_set_timer:(NSTimeInterval)timeInterval
                              handler:(void(^)(NSString *timeString))handlerBlcok
    {
        if (_timer == nil) {
            
            // 倒计时时间
            _valid = YES;
            _lock = dispatch_semaphore_create(1);
            __block int timeout = timeInterval;
            __block NSString *timeString = @"";
            
            if (timeout != 0) {
                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
                _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_semaphore_signal(self->_lock);
                        [self invalidate];
                        dispatch_async(dispatch_get_main_queue(), ^{
                            //handlerBlcok(0, 0, 0, 0);
                            handlerBlcok(timeString);
                        });
                    } else {
                        dispatch_semaphore_signal(self->_lock);
                        NSInteger days = (int)(timeout/(3600*24));
                        NSInteger hours = (int)((timeout-days*24*3600)/3600);
                        NSInteger minute = (int)(timeout-days*24*3600-hours*3600)/60;
                        NSInteger second = timeout-days*24*3600-hours*3600-minute*60;
                        dispatch_async(dispatch_get_main_queue(), ^{
                            //handlerBlcok(days, hours, minute, second);
                            if (days == 0) {
                                timeString = @"";
                            }
                            if (days > 0) {
                                timeString = [NSString stringWithFormat:@"%ld天%ld时%ld分%ld秒", days, hours, minute, second];
                            } else {
                                if (hours > 0) {
                                    if (hours < 10) {
                                        timeString = [NSString stringWithFormat:@"%0ld时%ld分%ld秒", hours, minute, second];
                                    } else {
                                        timeString = [NSString stringWithFormat:@"%ld时%ld分%ld秒", hours, minute, second];
                                    }
                                } else {
                                    if (minute > 0) {
                                        if (minute < 10) {
                                            timeString = [NSString stringWithFormat:@"%0ld分%ld秒", minute, second];
                                        } else {
                                            timeString = [NSString stringWithFormat:@"%ld分%ld秒", minute, second];
                                        }
                                    } else {
                                        if (second < 10) {
                                            timeString = [NSString stringWithFormat:@"%0ld秒", second];
                                        } else if (second == 0) {
                                            timeString = @"";
                                        } else {
                                            timeString = [NSString stringWithFormat:@"%ld秒", second];
                                        }
                                    }
                                }
                            }
                            handlerBlcok(timeString);
                        });
                        timeout--;
                    }
                });
                dispatch_resume(self->_timer);
            }
        }
    }
    
    /// 关闭定时器
    - (void)invalidate
    {
        dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
        if (_valid) {
            dispatch_source_cancel(_timer);
            _timer = NULL;
            _valid = NO;
        }
        dispatch_semaphore_signal(_lock);
    }
    
    - (void)dealloc
    {
        [self invalidate];
    }
    
    @end
    
    // 使用完定时器要销毁
    - (void)removeFromSuperview
    {
        [super removeFromSuperview];
        [_hoursCountDown invalidate];
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        [_hoursCountDown invalidate];
    }
    
    

    相关文章

      网友评论

          本文标题:iOS定时器——倒计时(天、时、分、秒)

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