美文网首页
iOS 毫秒倒计时列表

iOS 毫秒倒计时列表

作者: 王看山 | 来源:发表于2016-11-03 15:13 被阅读432次

近段的项目有个毫秒倒计时的需求,在网上找了好久,都没有找到明确的Demo或者毫秒倒计时的知识点,所以就借鉴了一些前辈的思路,和自己琢磨,然后成功把毫秒倒计时弄了出来。目前我知道的有两种做法,如下:

1.用一个定时器实现倒计时列表的毫秒倒计时

首先创建好定时器,如果不加入runloop中就会引发滑动表格时,倒计时停止的现象:

// 开启定时器
_timer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
_passTime = 0.0f;
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];

然后设置倒计时的时长,因为是列表的原因,所以就随机了20条以毫秒为单位的数据

_dataArray = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < 20; i++) {
  // 取秒为单位
  [_dataArray addObject:@(rand() % 600*1000)];
}

最后取表格可见cell,并记录好已经pass的时间,定时刷新cell的倒计时内容,此处有个注意的地方就是时间转换的问题,如果用1毫秒来倒计时的话个人感觉太耗性能了,所以改为10毫秒,毫秒倒计时位数正好也是两位,刚好满足需求。

//定时器刷新倒计时
- (void)timerAction {
  //取出屏幕可见cell
  NSArray *cells = _countdowntable.visibleCells;
  _passTime += 10.f;
  for (UITableViewCell *cell in cells) {
      NSIndexPath *indexPath = [_countdowntable indexPathForCell:cell];
      NSInteger index = indexPath.row;
      NSInteger remainTime = [_dataArray[index] integerValue];
      if (remainTime - _passTime <= 0) {
        cell.textLabel.text = @"00:00:00";
        [_dataArray removeObjectAtIndex:index];
        [_countdowntable deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
      } else {
        NSString *minute = [NSString stringWithFormat:@"%d", (int)((remainTime - _passTime)/1000/60)%60];
        NSString *second = [NSString stringWithFormat:@"%d", ((int)(remainTime - _passTime))/1000%60];
        CGFloat sss = ((int)((remainTime - _passTime)))%1000/10;
        NSString *ss = [NSString stringWithFormat:@"%.lf", sss];
        if (minute.integerValue < 10) {
            minute = [NSString stringWithFormat:@"0%@", minute];
        }

       if (second.integerValue < 10) {
           second = [NSString stringWithFormat:@"0%@", second];
       }

       if (ss.integerValue < 10) {
         ss = [NSString stringWithFormat:@"0%@", ss];
       }
         cell.textLabel.text = [NSString stringWithFormat:@"%@:%@:%@", minute, second, ss];
       }
    }
}

2.每个cell用一个定时器实现

这个跟第一个方法类似,但是它的定时器在cell里边创建,也就是说在不计算重用cell的情况,一个页面上有可能会同时存在N个定时器,比较耗性能,表示电脑在运行倒计时Demo的时候,风扇转的N快。

为了确保数据源也同步,传入数据源数组,然后每减少0.01s就替换一次数组中对应减少的值。

倒计时刷新的方法

- (void)countdownAction {
    if (_remainTime <= 0) {
        [self timerStop];
        _countdown.text = @"此Cell倒计时完成";
    } else {
        _remainTime -= 10;
        NSString *hour = [NSString stringWithFormat:@"%ld", _remainTime/1000/60/60];
        NSString *minute = [NSString stringWithFormat:@"%ld", _remainTime/1000/60%60];
        NSString *second = [NSString stringWithFormat:@"%ld", _remainTime/1000%60];
        CGFloat sss = _remainTime%1000/10;
        NSString *ss = [NSString stringWithFormat:@"%.lf", sss];
        if (hour.integerValue && hour.integerValue < 10) {
            hour = [NSString stringWithFormat:@"0%@", hour];
        }
        if (minute.integerValue < 10) {
            minute = [NSString stringWithFormat:@"0%@", minute];
        }
        if (second.integerValue < 10) {
            second = [NSString stringWithFormat:@"0%@", second];
        }
        if (ss.integerValue < 10) {
            ss = [NSString stringWithFormat:@"0%@", ss];
        }
        _countdown.font = [UIFont systemFontOfSize:28];
        if (hour.integerValue) {
            _countdown.text = [NSString stringWithFormat:@"%@:%@:%@:%@", hour, minute, second, ss];
        } else {
            _countdown.text = [NSString stringWithFormat:@"%@:%@:%@", minute, second, ss];
        }
    }
}

然后在cell中定时器开启的用法也跟方法1一样,同样是添加到runloop中

if (!_timer && _remainTime > 0) {
   _timer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(countdownAction) userInfo:nil repeats:YES];
   [[NSRunLoop currentRunLoop] addTimer:_timer forMode:UITrackingRunLoopMode];
 }

差不多就这些了,github上面有Demo,希望能帮到你,如有更好的想法,欢迎留言...

相关文章

网友评论

      本文标题:iOS 毫秒倒计时列表

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