iOS 毫秒倒计时列表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 毫秒倒计时列表相关的知识,希望对你有一定的参考价值。

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

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

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

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

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

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

倒计时刷新的方法

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

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

列表滚动后计时器中断

【中文标题】列表滚动后计时器中断【英文标题】:Timer breaks after List scroll 【发布时间】:2020-01-09 21:47:25 【问题描述】:

我有一个带计时器的课程(每毫秒更新一次)。

class TimeCount 
    let currentTimePublisher = Timer.TimerPublisher(interval: 0.001, runLoop: .main, mode: .common)
    let cancellable: AnyCancellable?

    init() 
        self.cancellable = currentTimePublisher.connect() as? AnyCancellable
    

    deinit 
        self.cancellable?.cancel()
    

我还有一个 TimerView 对象的 List()

List() 
    ForEach(self.timers)  timer in
        TimerPlusView(timer: timer)
    

在每个对象内部我都有一个 Text 来更新其内容并监听计时器

Text("\(currentTime.timeIntervalSince(timer.time ?? Date()))")
    .font(.largeTitle)
    .fontWeight(.bold)
    .foregroundColor(.black)
    .opacity(0.5)
    .onReceive(timeCount.currentTimePublisher)  newCurrentTime in
        self.currentTime = newCurrentTime
    

问题是,在(不是同时)滚动列表大约 100 像素之后,计时器停止工作,标签停止更新,我不知道为什么。

我得到的行为:

UPD:这是完整项目的链接以供参考。 https://www.dropbox.com/s/47zoizfqp6upz1e/TimerMinimal.zip?dl=0

【问题讨论】:

从您的代码中,我不知道为什么您的计时器停止更新。也许您可以发布一个指向最小 xcode 项目的链接,以帮助其他人在他们的机器上重现它。也许这也是一个模拟器错误 - 您是否也在设备上尝试过? 是的,我也没有。NP,这是项目的链接dropbox.com/s/47zoizfqp6upz1e/TimerMinimal.zip?dl=0 是的,我尝试过同时使用模拟器和真实设备——到处都是一样的交易。 当滚动视图滚动时,另一个运行循环会接管。您还应该将计时器添加到跟踪运行循环中。 ***.com/questions/7551411/… 【参考方案1】:

我认为问题出在 Xcode 中。或者至少是一些非常无证的东西。或者只是一个谜。

当从表视图(如旧的 dequeue-stuff)重新使用视图时,似乎会出现此问题,然后以某种方式导致订阅丢失,并且不再发布任何计时器事件。

不过,我找到了类似的解决方法。

TimerPlusView.swift 中,将.onReceive 处理程序移动到正文视图的最底部,例如

var body: some View 

    Button(action: 
        self.timer.title = "Tapped"
    ) 
        VStack(alignment: .leading) 
            Text(timer.title ?? "New Timer")
                .font(.largeTitle)
                .fontWeight(.bold)
                .foregroundColor(.black)
            Text("\(currentTime.timeIntervalSince(timer.time ?? Date()))")
                .font(.largeTitle)
                .fontWeight(.bold)
                .foregroundColor(.black)
                .opacity(0.5)
            // onReceive doesn't seem to work here:
            //.onReceive(timeCount.currentTimePublisher)  newCurrentTime in
            //  self.currentTime = newCurrentTime
            // 

        
    
    .buttonStyle(BorderlessButtonStyle())
    .contextMenu 
        Button(action: 
            self.context.delete(self.timer)
        ) 
            Text("Delete")
        
    
    // here, onReceive works:
    .onReceive(timeCount.currentTimePublisher)  newCurrentTime in
      self.currentTime = newCurrentTime
    

【讨论】:

以上是关于iOS 毫秒倒计时列表的主要内容,如果未能解决你的问题,请参考以下文章

列表滚动后计时器中断

毫秒数变成时分秒倒计时

PHP精确到毫秒秒杀倒计时实例

Js倒计时代码精确到毫秒。

一个倒计时显示的毫秒数(模仿拼多多)

请PHP高手帮修改一个倒计时的代码.