1

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

Lukesivi
  • 2,206
  • 4
  • 25
  • 43

1 Answers1

2

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
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • What if I have to query an x amount of different dates with different times? How can I store them all in a variable? SHouldn't it be done through an array? – Lukesivi Oct 28 '15 at 17:50
  • Sure, you could make `countdown` an array of times `var countdown = [Int]()` then you'd refer to each one by index such as `countdown[0]`, `countdown[1]`, etc. Just replace `countdown` in the above logic with `countdown[n]` where `n` is the index of the timer you are currently formatting. If you have a fixed number of timers, for example 5, you could just do `var countdown = [0,0,0,0,0]`. If you want to allocate space for `n` timers then `var countdown = [Int](count: n, repeatedValue: 0)`. – vacawama Oct 28 '15 at 17:54
  • Thanks for the response btw... How would this work with the intArray/timeCreatedString array I have? How would i divide that array I'm appending to like you did in the above answer with the variable? The code works when I have only a variable, but i'm confused as to how to do the same thing but just for for index values in an array... – Lukesivi Oct 28 '15 at 17:59
  • See updated answer. Each array element holds the current value of 1 timers in seconds. The value is split into hours, minutes, and seconds when displayed. – vacawama Oct 28 '15 at 18:14
  • Hey one question: when I print to the logs the array value i get the full numbers without the format. How do I format it without using the `print(format())` method? Ultimately, I'm having problems putting it on the UI. I just get the first, raw numeric value of the time: `6871` and it doesn't move. This is happening in the cellForRowAtIndexPath like this: `myCell.secondLabel.text = ("\(timerInt[indexPath.row])")` any ideas how to format/trigger the timer here as well? – Lukesivi Oct 28 '15 at 18:49
  • how can I format the array? Having loads of trouble... Just able to print to the logs... – Lukesivi Oct 28 '15 at 20:09
  • To setup space for 20 timers: add this property to your view controller class: `var timerInt = [Int](count: 20, repeatedValue: 0)`. In `countDown()` loop through this array decrementing all of the timers. You need to call `tableView.reloadData()` to get the displayed rows to redisplay. Set up your label like this: `myCell.secondLabel.text = String(format: "%02d:%02d:%02d", hours, minutes, seconds))` after calculating `hour`, `minutes` and `seconds` from `timerInt[indexPath.row]`. – vacawama Oct 28 '15 at 20:47
  • I added the hours minutes and seconds variables from the countDown function into the cellForRowAtIndexPath to calculate the three from the `timerInt[indexPath.row]`. The seconds are counting down are now counting down by 3. – Lukesivi Oct 29 '15 at 10:02
  • Only the countDown function should decrement the values of the timers. CellForRowAtIndexPath should only format them for display. – vacawama Oct 29 '15 at 10:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93662/discussion-between-rinyfo4-and-vacawama). – Lukesivi Oct 29 '15 at 10:24
  • In the logs, I can see the the timer is printing correctly. But in the label it's counting down by 3. I don't understand why that's happening... – Lukesivi Oct 29 '15 at 11:00
  • Got the answer. My timer method wasn't in the right location. I put it outside of the query. It was being queried 3x. – Lukesivi Oct 29 '15 at 12:31
  • http://stackoverflow.com/questions/33414661/why-is-my-timer-counting-down-by-3-every-second/33414662#33414662 – Lukesivi Oct 29 '15 at 12:47