Ios 计时器,用于从时间戳开始计算时间

Ios 计时器,用于从时间戳开始计算时间,ios,swift,Ios,Swift,我有一个表视图,其中包含动态数量的UITableViewCells。填充单元格的数据来自Firebase。每个记录(因此每个单元格)都有一个recordTimestamp字段,该字段是该记录添加到Firebase时的Unix时间戳 我试图找到一种方法/最佳实践,在每个单元格中创建一个每秒更新一次的“计数器”,以显示自recordTimestamp以来的分钟/秒数。计数器应继续每秒递增一次,直到点击单元格中的按钮 我曾尝试使用timer对象每秒调用一次函数,将recordTimestamp与当前时

我有一个表视图,其中包含动态数量的UITableViewCells。填充单元格的数据来自Firebase。每个记录(因此每个单元格)都有一个
recordTimestamp
字段,该字段是该记录添加到Firebase时的Unix时间戳

我试图找到一种方法/最佳实践,在每个单元格中创建一个每秒更新一次的“计数器”,以显示自
recordTimestamp
以来的分钟/秒数。计数器应继续每秒递增一次,直到点击单元格中的按钮

我曾尝试使用timer对象每秒调用一次函数,将
recordTimestamp
与当前时间进行比较。然后,点击按钮,它将触发定时器。使失效。这种方法是可行的,但是运行了大约20秒之后,计数器就完全不同步了,有些计数器落后了几秒钟。这也是令人难以置信的滞后-只有大约10行在表中,你几乎不能顺利滚动

对此有何建议

编辑:按要求编码。现在,我只是想让它正确地从0开始计数。一旦我得到排序,我将添加逻辑,首先计算时间差,然后每秒递增

class newRequestCell: UITableViewCell {

    @IBOutlet weak var acceptButton: UIButton!
    @IBOutlet weak var timeSinceRequest: UILabel!

    var timer = Timer()
    var counter = 0


    func setRequestCell(customerRequest: customerRequest) {

        customerName.text = String(customerRequest.customerName)
        orderNumber.text = String(customerRequest.orderNumber)

        timer = Timer.scheduledTimer(timeInterval: 1, target:self, selector: #selector(self.updateCounter), userInfo: nil, repeats: true)

    }


    @objc func updateCounter() {
        counter += 1
        timeSinceRequest.text = String(counter)
    }


    @IBAction func acceptButtonTapped(_ sender: Any) {
        //TODO: stop timer, make call to Firebase updating record status        
    }

}

这里有一个计数不一致的例子。这两个电池同时被加载,但在大约6分钟后,第二个计时器落后了大约2分钟


非常感谢@DanielStorm和@Paulw11的洞察,他们给出了这个答案

计时器的所有逻辑都已移出单元格并进入主ViewController

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let customerRequest = activeRequestsArray[indexPath.row]

        let cell = tableView.dequeueReusableCell(withIdentifier: "newRequestCell") as! newRequestCell
        cell.setRequestCell(customerRequest: customerRequest)


        let requestTime = NSDate(timeIntervalSince1970: TimeInterval(activeRequestsArray[indexPath.row].requestTimestamp/1000))

        let calendar = Calendar.current
        let timeComponents = calendar.dateComponents([.hour, .minute, .second], from: requestTime as Date)
        let nowComponents = calendar.dateComponents([.hour, .minute, .second], from: Date())

        let difference = calendar.dateComponents([.second], from: timeComponents, to: nowComponents).second!

        cell.timeSinceRequest.text = String(difference)

        cell.buttonPressed = {
               print(indexPath.row)
               //TODO: delete cell on button tap
         }

        return cell
    }

请将相关代码添加到您的问题中。确保您的数据存储了
日期
。在cellForRow中,您可以使用
timeIntervalSince(Date)
获取秒数和所需格式(例如,小时、分钟、秒等)。当您的计时器滴答作响时,只需重新加载可见单元格(不要重新加载整个表视图)@DanielStorm相关代码片段已添加。单元格不应对计时器负责。单元格被重用,这会导致倒计时不一致问题。您很可能希望您的控制器负责计时器。当计时器更新时,您的控制器会更新与计时器对应的单元格标签。非常感谢你们!我把你的两个建议结合起来,现在效果很好。丹尼尔-现在我已经将它移动到主viewcontroller,时间安排更加一致。Paul-将逻辑放入我的
UITableViewDataSource
中的
cellForRow
中,trickI不确定为什么会被否决,我愿意接受改进解决方案的建议。我分享了我的解决方案,希望其他人在遇到与我相同的问题时也能从中受益