iOS用定时器刷新列表Cell进行行倒计抢单功能

42 篇文章 0 订阅

1.简介

  • 有时候我们需要在UITableView中的cell做一些类似京东天猫的倒计时抢购的功能,时间到了会发送一个通知提醒用户可以抢购了。
  • 其原理无非是通过定时器刷新UITableView,这里有两种方式:
    1. 在每一个cell中都添加一个定时器,计算剩余时间,然后实时刷新更改对应UILable的文字;
    2. 开启一个定时器,然后遍历数据源计算剩余时间,然后刷新UITableView,考虑到内存开销,本文中采用的第二种方式;

2.创建定时器

  • 创建定时器有3种方法(可参考这里介绍:OC中定时器的三种实现方式):

    1. NSTimer:虽然简单易用,但是定时不准确;
    2. CADisplayLink:能保证和屏幕刷新率相同的频率,将特定的内容画到屏幕上,其实时间间隔是和屏幕刷新频率相关联的;
    3. dispatch_source:也称为GCD定时器,不受 runloop 模式的影响,使用 dispatch_source 能够实现没有延迟的定时器,即可以实现高精度定时,所以本为中采用dispatch_source定时。
  • 具体步骤:当获取的TableView数据源后,开启定时器计算时间差

//创建GCD定时器
    gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    //设置定时器
    dispatch_source_set_timer(gcdTimer, dispatch_walltime(NULL, 0), 1ull * NSEC_PER_SEC, 0);
    //设置定时器任务
    dispatch_source_set_event_handler(gcdTimer, ^{
    //遍历数据源,计算时间差,并且给对应的cell设置对应的时间差
        for (int index = 0; index<weakSelf.dataSource.count; index++) {
            UntreatedOrderModel * model = weakSelf.dataSource[index];
            model.countdownTime = [weakSelf dateTimeIntervalWithEndTime:model.qdsxTime];
            __block typeof(model) blockModel = model;
            dispatch_async(dispatch_get_main_queue(), ^{
                UntreatedOrderCell * cell = [weakTableV cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
                cell.model = blockModel;
            });
        }
    });
    // 启动任务,GCD计时器创建后需要手动启动
    dispatch_resume(gcdTimer);

3.计算时间差

  • 计算到现在的时间差:timeIntervalSinceNow,计算两个时间点之间的时间差:timeIntervalSinceDate:,计算的时间差是以秒为单位的,所以可以得到对应的天、时、分、秒。
-(NSString *)dateTimeIntervalWithEndTime:(NSString *)endTime{
    //设定时间戳样式
    NSDateFormatter * dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate * endD = [dateFormatter dateFromString:endTime];
    NSTimeInterval value = [endD timeIntervalSinceNow];
    int second = (int)value %60;//秒
    int minute = (int)value / 60%60;//分
    int hour = (int)value / 3600%24;//时
    int day = (int)value / (24 *3600);//天
    NSString *str;
    if (day > 0) {
        str = [NSString stringWithFormat:@"%d天%d时%d分%d秒",day,hour,minute,second];
    }else if (day==0 && hour > 0) {
        str = [NSString stringWithFormat:@"%d时%d分%d秒",hour,minute,second];
    }else if (day==0 && hour==0 && minute>0) {
        str = [NSString stringWithFormat:@"%d分%d秒",minute,second];
    }else if (day==0 && hour==0 && minute==0 && second>0){
        str = [NSString stringWithFormat:@"%d秒",second];
    }else{
        str = @"已超时";
    }
    return str;
}

注意:这里为啥调用reloadData方法刷新UITableView,而是获取每一个cell然后给cell赋值,如果频繁调用reloadData去刷新UITableView,会发现有事件冲突,滚动的时候不够流畅,滚动的位置有时候并不是自己想要的,虽然有人说可以设置NSRunLoopModeNSRunLoopCommonModes来防止事件冲突,但我试了并不行;而获取每一个cell然后给cell赋值是丝滑流畅的。(当然肯定有方法可以解决,有知道的还烦请不吝赐教)。

4.效果图

效果图

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值