Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple timers in UITableViewCell (Swift)

I have UITableViewcells that are created at different moments in time and I would like each one of them to have an independent timer that triggers when the object is added with reloadData()

This is what I have done so far

import UIKit

var timer = Timer()
var blinkStatus:Bool! = false
var time = 300


class LiveViewCell: UITableViewCell {

    let str = String(format:"%02d:%02d", (time / 60), (time % 100))
    func processTimer() {

        if time > 0 {
            time -= 1
            timeRemainingLbl.text = String(time)
        } else if time == 0 {
            timer.invalidate()
            timeRemainingLbl.text = "Due!"
            timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(LiveViewCell.blinkTimer), userInfo: nil, repeats: true)

        }

    }

    func blinkTimer() {
        if blinkStatus == false {
            timeRemainingLbl.textColor = UIColor(red:1.00, green:0.00, blue:0.00, alpha:1.0)
            blinkStatus = true
        } else if blinkStatus == true {
            timeRemainingLbl.textColor = UIColor.clear
            blinkStatus = false
        }

    }


    @IBOutlet weak var tableNumberLeftLabel: UILabel!
    @IBOutlet weak var guestNumbersLabel: UILabel!

    @IBOutlet weak var timeInTableLabel: UILabel!
    @IBOutlet weak var tableNumberLbl: UILabel!
    @IBOutlet weak var timeRemainingLbl: UILabel!


    var table: Table!


    func configureLiveCell(_ NT: Table) {

        layer.cornerRadius = 20
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(LiveViewCell.processTimer), userInfo: nil, repeats: true)
        tableNumberLbl.text = "T" + String(NT.number)
        timeRemainingLbl.text = String(time)

    }
}

The problem comes when configureLiveCell gets called whenever I create a new cell. The timer seems to speed up and I would like each timer to be independent.

like image 592
Christian Ray Leovido Avatar asked Mar 10 '23 18:03

Christian Ray Leovido


1 Answers

Override the prepareForReuse method.

override func prepareForReuse() {
    super.prepareForReuse()

    timer.invalidate()
}

This will be called just before a cell is returned to be used by another row. By invalidating the timer here, your configureLiveCell doesn't create yet another timer.

BTW - you should also add a deinit method and invalidate the timer there too.

You also make the timer property optional and set it to nil after you invalidate it. And of course you need to add proper checks to deal with it being an optional.

And one last change you must make is to change timer, time, and blinkStatus so they are instance variables by moving them inside the class.

like image 148
rmaddy Avatar answered Mar 28 '23 21:03

rmaddy