Search code examples
arraysswiftnsdatecountdowndecrement

Swift countDown timer Logic


I'm creating a countdown timer by the day, hour and second. I'm currently storing them in a String array while also converting them into an Int ( using map() ) so that I can countdown/decrement when I make the values into a label.

The current output when printing to the logs is: ["[68168]", "[68188]", "[68243]", "[68281]"]

I'm having trouble forming the logic of a countDown function so that when seconds hits "0", 1 minute goes down, and after 59 minutes 1 hour is decremented, etc., until it hits "00:00:00".

In each index, I have the 3 values of [Hour, Minute, Second]. But I have several indexes.

Currently I'm taking the Hour * 3600, the minute * 60 + the second. My question is how I can divide this up and break it down in the countDown function...

Here is my code:

   //Here I'm querying and converting the objects into Hour, Minute, Seconds.

 var createdAt = object.createdAt
            if createdAt != nil {

                let calendar = NSCalendar.currentCalendar()
                let comps = calendar.components([.Hour, .Minute, .Second], fromDate: createdAt as NSDate!)
                let hour = comps.hour * 3600
                let minute = comps.minute * 60
                let seconds = comps.second
                let intArray = [hour, minute, seconds]

                //Now i'm appending to the String array below. 

                self.timeCreatedString.append("\(intArray)")

               var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("countDown"), userInfo: nil, repeats: true)


            }


             func countDown() {

                     //completely stuck as to how to decrement/divide up the values so that I can display it as: 23:49:01 (Hours, minutes, seconds). 

                 }

How can I form it so that each element within each index countdowns separately? ex: "23: 59: 59"

PS, this is being built on a TableViewController. I want to print this to a label that is in a cell View Controller in the cellForRowAtIndexPath method


Solution

  • Keep your countdown time in seconds in a single variable called countdown:

    var countdown = 7202 // two hours and two seconds
    

    When it comes time to display it, break it into hours, minutes, and seconds and use the String(format:) constructor to format it:

    // loop 5 times to demo output    
    for _ in 1...5 {
        let hours = countdown / 3600
        let minsec = countdown % 3600
        let minutes = minsec / 60
        let seconds = minsec % 60
        print(String(format: "%02d:%02d:%02d", hours, minutes, seconds))
        countdown--
    }
    

    Output:

    02:00:02
    02:00:01
    02:00:00
    01:59:59
    01:59:58
    

    If you have more than one timer, keep them in an array:

    // Array holding 5 different countdown timers referred to as
    // timers[0], timers[1], timers[2], timers[3] and timers[4]
    var timers = [59, 61, 1000, 3661, 12345]
    
    for i in 0 ..< times.count {
        let hours = timers[i] / 3600
        let minsec = timers[i] % 3600
        let minutes = minsec / 60
        let seconds = minsec % 60
        print(String(format: "%02d:%02d:%02d", hours, minutes, seconds))
    }
    

    Output:

    00:00:59
    00:01:01
    00:16:40
    01:01:01
    03:25:45