Search code examples
iosswiftnstimer

Tracking the time on each Cell like Hours App


I have a UITableViewCell with some buttons that have time values like the hours app. I would like to track the time on each cell whenever I click on the button related to that cell like the hours app does - as shown in the screen shot below.

I already know how deal with timers: The function below is used to update the time on a general label :

var startTime = TimeInterval()
var timer : Timer?


func updateTime() {

        let currentTime = NSDate.timeIntervalSinceReferenceDate

        //Find the difference between current time and start time.

        var elapsedTime: TimeInterval = currentTime - startTime

        //calculate the minutes in elapsed time.
        let minutes = UInt8(elapsedTime / 60.0)

        elapsedTime -= (TimeInterval(minutes) * 60)

        //calculate the seconds in elapsed time.
        let seconds = UInt8(elapsedTime)

        elapsedTime -= TimeInterval(seconds)

        //add the leading zero for minutes, seconds and millseconds and store them as string constants

        let strMinutes = String(format: "%02d", minutes)
        let strSeconds = String(format: "%02d", seconds)

        //concatenate minuets, seconds and milliseconds as assign it to the UILabel

        self.timeLabel?.text = "\(strMinutes):\(strSeconds)"
        //labelShake(labelToAnimate: self.timeLabel!, bounceVelocity: 5.0, springBouncinessEffect: 8.0)

    }

I can put the following code in ViewDidLoad to start the timer:

        timer = Timer()
        timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
        startTime = NSDate.timeIntervalSinceReferenceDate

For tapping a button in a cell, I add a tag on the cell's button to track the cell that I tapped on as shown below

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


        //...
        cell.timerViewButton.tag = indexPath.row
        cell.timerViewButton.addTarget(self, action: #selector(startTimerForCell), for: UIControlEvents.touchUpInside)
        //...

       return cell

}

// I can track the button clicked here.

func startTimerForCell(sender : UIButton) {


        print("SelectedCell \(sender.tag)")


    }

Can anyone help with how can I change the button title on the cell clicked to the do the counting and potential stopping the timer when I click on the button

enter image description here


Solution

  • From my understanding, your problem is want to track each timer states. Just keep in mind that UITableViewCell is reusable and it will keep change when you scroll or view it.

    Normally I will use array to easily keep track all those states or values in cell.

    So, in your controller will have class variables probably as below

    struct Timer {
        let start = false
        let seconds = 0
        // can have more properties as your need
    }
    
    var timers = [Timer]()
    

    Then, in your start function startTimerForCell will keep monitor those array.

    func startTimerForCell(sender : UIButton) {
        let timer = timers[sender.tag]
        if timer.start {
            // stop the timer
            timers[sender.tag].start = false
        }
        else {
            // stop the timer
            timers[sender.tag].start = true
        }
    }