滚动 UITableView 期间计时器将重置并停止运行

Posted

技术标签:

【中文标题】滚动 UITableView 期间计时器将重置并停止运行【英文标题】:Timer will reset and stop running during scrolling UITableView 【发布时间】:2018-06-08 16:43:07 【问题描述】:

timer.gif

↑↑↑↑↑↑↑↑↑我在这个GIF中显示问题↑↑↑↑↑

tableView 单元格中有一个计时器和一个stratButton,当我点击按钮时,timeLabel 将开始运行。

现在的问题是,当我将正在运行的计时器滚动到屏幕外并向后滚动时,计时器将重置并停止。

希望有人可以帮助我!我检查了许多解决方案,但它们对我不起作用!我快哭了。

我的 cellForRow:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! TimerTableViewCell

    cell.timer?.invalidate()
    let item = myTimerList[indexPath.row]
    cell.timerName.text = item.timerName
    cell.secondLeftLabel.text = "\(item.timerSecond)"      
    return cell


我创建了一个包含我的代码的小项目供您修改:https://app.box.com/s/axluqkjg0f7zjyigdmx1lau0c9m3ka47

【问题讨论】:

不要对每个单元格使用计时器。请参阅***.com/questions/49246036/… 以获得更好的解决方案 【参考方案1】:

你需要保存每个单元格的状态

class Service 

   static let shared = Service()

   var myTimerList = [TimerClass]()

//

在这里我添加了另外 2 个变量,为什么 timerName 仍然存在,尽管您必须将它们初始化为相同,因为 current 将保持变化的值

class TimerClass 

    let timerSecond : Int
    let timerName : String
    var current: Int
    var isPlaying = false

    init(second:Int, name:String) 

        timerSecond = second
        timerName = name
        current = second
     


//

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! TimerTableViewCell


    let item = Service.shared.myTimerList[indexPath.row]
    cell.tag = indexPath.row // to access the array inside the cell
    if item.isPlaying 
      cell.play()     // add play method to the cell it has same button play action
    
    else 
      cell.timer?.invalidate()
    
    cell.timerName.text = item.timerName
    cell.secondLeftLabel.text = "\(item.current)"      
    return cell


//

单击按钮时在单元格内,将 isPlaying 属性更改为 true 并在像这样停止时更改为 false

// here self is the cell itself 

Service.shared.myTimerList[self.tag].isPlaying = true

还有当计时器滴答声改变时

Service.shared.myTimerList[self.tag].current = // value 

【讨论】:

嘿,汗!感谢您的帮助,我将您的代码集成到我的代码中,现在计时器不会重置,但如果我将其滚动到屏幕外,它仍然会停止运行,我尝试更改一些代码来修复它,但它没有'不起作用...我想我可能误解了您上面提到的一些步骤...您能帮我检查一下我在哪里犯了错误吗?我更新了我的代码并放在这里:app.box.com/s/hpu6xidy6c1gtcyp6d9uq6p5xwft6rr2【参考方案2】:

您正在重用UITableViewCell。这意味着一旦单元格离开屏幕,它将被重新用于进入屏幕的单元格。每当它发生时,它都会调用委托方法 - 意味着cell.timer?.invalidate() 会被一次又一次地调用。

【讨论】:

是的,但是当我删除 cell.timer?.invalidate() 时,如果我将其滚动出去,我的计时器将被重置并停止......你能给我一些更好的解决方案吗?【参考方案3】:

cellForRowAt 方法中删除cell.timer?.invalidate(),因为每次滚动tableView 时都会调用此方法来显示新单元格。在您的情况下,当您为一个单元格启动计时器并且该单元格不在视图中时,下次您滚动以将该单元格再次带到视图 cell.timer?.invalidate() 会导致它停止。

【讨论】:

不,我删除了它,但我的计时器仍然重置并停止运行......你能告诉我另一种方式吗?这里是资源:app.box.com/s/axluqkjg0f7zjyigdmx1lau0c9m3ka47

以上是关于滚动 UITableView 期间计时器将重置并停止运行的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 滚动后 UITableView contentOffset 重置

UITableView 在滚动期间停止渲染

快速滚动期间uitableview上的删除按钮

滚动 UITableView 期间未调用 audioPlayerDidFinishPlaying

在 XCUI TestCase 期间最后停止在 UITableView 上滚动

如何检测 UITableView 标题何时滚动?