美文网首页
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