KawaiKx KawaiKx - 1 year ago 89
iOS Question

Timer in the for loop in Swift

I want to run the timer inside a loop for a given number of loops only. There is an outer loop also.

user will input how many repetitions he wants, how many counts in each repetition, time gap between two counts.

app will show the counts of each repetition. when all repetitions done, app will stop the timer.

But I am finding it difficult. It looks like timer ignores the for loop and is a loop in itself which stops when we issue timer.invalidate() only.

Any thoughts about it?

for x in 0...HowManyRepetitions {

counter = 0
CountLabel.text = "\(counter)"
RepetitionLabel.text = "\(x) / \(HowManyRepetitions)"

for y in 0...HowManyCounts {

timer = NSTimer.scheduledTimerWithTimeInterval(PeriodBetween, target: self, selector: updateCounter, userInfo: nil, repeats: true)



Answer Source

Repetition count needs to be managed in the timer handler.

You usually keep timer as an instance property. (You may need to invalidate the timer, for example, when viewWillDisappear(_:).)

So, you may need to write something like this in your class:

var timer: NSTimer?
func startTimer(howManyCounts: Int, periodBetween: NSTimeInterval) {
    let userInfo: NSMutableDictionary = [
        "counter": 0,
        "howManyCounts": howManyCounts,
        "myName": "Timer"
    self.timer = NSTimer.scheduledTimerWithTimeInterval(periodBetween, target: self, selector: #selector(timerHandler), userInfo: userInfo, repeats: true)

@objc func timerHandler(timer: NSTimer) {
    guard let info = timer.userInfo as? NSMutableDictionary else {
    var counter = info["counter"] as? Int ?? 0
    let howManyCounts = info["howManyCounts"] as? Int ?? 0
    let myName = info["myName"] as? String ?? "Timer"
    counter += 1

    print("\(myName):\(counter)") //countLabel.text = "\(counter)"

    if counter >= howManyCounts {
    } else {
        info["counter"] = counter

Start the timer from somewhere in the method of the same class as:

    startTimer(10, periodBetween: 3.0)

I don't understand why you need outer loop, but if you want to make multiple timers working, you need to keep all timers.

var timers: [NSTimer] = []
func startTimers(howManyRepetitions: Int, howManyCounts: Int, periodBetween: NSTimeInterval) {
    timers = []
    for x in 1...howManyRepetitions {
        let userInfo: NSMutableDictionary = [
            "counter": 0,
            "howManyCounts": howManyCounts,
            "myName": "Timer-\(x)"
        timers.append(NSTimer.scheduledTimerWithTimeInterval(periodBetween, target: self, selector: #selector(timerHandler), userInfo: userInfo, repeats: true))

Start the timers as:

    startTimers(3, howManyCounts: 4, periodBetween: 1.0)