Search code examples
iosswiftnstimer

Displaying decreasing minutes and seconds on 5 labels in Swift


I am making an app in Swift which has a countdown timer that has to display minutes and seconds on 5 labels, to be exact, this is the formation:

[9][9][9] : [5][9]

// 999:59

So, in a principle which old odometers in cars used to count mileage, or one of those old flipping number clocks.

I will be using labels just as a testing model, later they will be replaced by image sets but I need the logic for the number display.

I managed to make a simple countdown using NSTimer.scheduledTimerWithTimeInterval(1.0...) and a separate function where I subtract one number from the total number which is written or declared. i.e.

var initialTime:Int = 60   
var timerSeconds = NSTimer()

func timerTick() {
    timerSeconds = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "startCount", userInfo: nil, repeats: true)
} 

func startCount() {
    initialTime--
}

And displaying the total time is no issue, but to separate the total time into minutes and seconds, AND to separate those two into 3 labels for minutes and 2 for seconds...I've been trying for hours and I can't think of anything. I am relatively new to swift so pardon if I missed out something. Thanks!


Solution

  • This isn't specific to Swift. Using the timer correctly is a Foundation classes question.

    Calculating the different digits is basic computer math.

    Don't decrement a counter each time your timer fires. Timers sometimes "miss" (fail to get called) if your app gets busy.

    Instead, record the NSDate.timeIntervalSinceReferenceDate() + secondsToCompletion when you start the timer.

    let finishedInterval = 
      NSDate.timeIntervalSinceReferenceDate() + secondsToCompletion
    

    Then each time the timer fires, calculate the new remaining seconds and use that for your math:

    let remainingSeconds = Int(round(finishedInterval -
      NSDate.timeIntervalSinceReferenceDate()))
    //Then do math on the time to get your digits:
    
    let secondsOnesPlace = remainingSeconds % 10
    let secondsTensPlace = (remainingSeconds % 60) / 10
    
    let remainingMinutes  = remainingSeconds / 60
    
    
    let remainingMinutesOncePlace = remainingMinutes % 10
    let remainingMinutesTensPlace = (remainingMinutes / 10) % 10
    let remainingMinutesHundredsPlace = (remainingMinutes / 100) % 10
    
    println("\(remainingMinutesHundredsPlace)\(remainingMinutesTensPlace)\(remainingMinutesOncePlace):\(secondsTensPlace)\(secondsOnesPlace)")
    

    Then use all the "...place" values to set your label digits/images.