为什么Timer / Countdown总是在UITableViewCell中重置为初始值

时间:2019-05-08 20:09:08

标签: ios swift uitableview

我正在TableViewCell中创建倒数计时器。并且运行良好。但是当我向下滚动然后向上滚动时,单元格计时器将被重置为初始值。我不明白我在这里做什么,所以它不会刷新或重置为初始值。请帮我的哥们帮帮我。

我的TableViewCell类代码为:

class DealOfferCell: UITableViewCell {
    @IBOutlet weak var CellCardView: UIView!
    @IBOutlet weak var CellBurgerKingImage: UIImageView!
    @IBOutlet weak var CellImageView: UIImageView!
    @IBOutlet weak var CellGetOffLabel: UILabel!
    @IBOutlet weak var CellOnAWhopperLabel: UILabel!
    @IBOutlet weak var CellDealEndsOnLabel: UILabel!
    @IBOutlet weak var CellDealItemNameLabel: UILabel!

    @IBOutlet weak var DealLeftButton: UIButton!

    private var timer: Timer?
    fileprivate var timeCounter: Double = 0

    var expiryTimeInterval: TimeInterval? {
        didSet {
            if timer == nil
            {
                startTimer()
                RunLoop.current.add(timer!, forMode: .commonModes)
            }
        }
    }

    private func startTimer() {
        if let interval = expiryTimeInterval {
            timeCounter = interval
            if #available(iOS 10.0, *) {
                timer = Timer(timeInterval: 1.0,
                              repeats: true,
                              block: { [weak self] _ in
                                guard let strongSelf = self else {
                                    return
                                }
                                strongSelf.onComplete()
                })
            } else {
                timer = Timer(timeInterval: 1.0,
                              target: self,
                              selector: #selector(onComplete),
                              userInfo: nil,
                              repeats: true)
            }
        }
    }

    @objc func onComplete() {
        guard timeCounter >= 0 else {
            // btnGoForTest.isUserInteractionEnabled = false
            CellDealEndsOnLabel.text = "Time ended."
            timer?.invalidate()
            timer = nil
            return
        }

        // btnGoForTest.isUserInteractionEnabled = true
        let hours = Int(timeCounter) / 3600
        let minutes = Int(timeCounter) / 60 % 60
        let seconds = Int(timeCounter) % 60

        CellDealEndsOnLabel.text = "DEAL ENDS ON " + String(format:"%02i:%02i:%02i", hours, minutes, seconds)

        timeCounter -= 1
        print("\(timeCounter)")
    }

    override func prepareForReuse() {
        super.prepareForReuse()

        timer?.invalidate()

        timer = nil
    }
}

以及CellForIndexPath中的代码:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    let cell = DealsOffersTableView.dequeueReusableCell(withIdentifier: "MapCell", for: indexPath) as! MapCell
    let getTime1 : Double = Double(500)
    cell.expiryTimeInterval = getTime1
}

1 个答案:

答案 0 :(得分:1)

您不应在单元格中存储易失性数据,例如到期日期。当用户滚动时,单元将被丢弃并重新使用。您应该将到期日期存储在数据模型对象(通常是数组)中。然后,在tableView(_: cellForRowAt:)方法中,应该从模型中获取数据并用于配置单元格。

您的代码无法正常工作,因为您试图将expiryTimeInterval设置为单元格的属性。滚动时,从屏幕上滚动的单元格将被回收并重新使用以显示不同indexPaths的数据。