5

Say I had this loop:

count = 0

for i in 0...9 {

    count += 1

}

and I want to delay it.

Delay function:

// Delay function
func delay(_ delay:Double, closure:@escaping ()->()) {

DispatchQueue.main.asyncAfter( deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)

}

.

This means if I want to increase count by 1 every second, I would do:

count = 0

for i in 0...9 {

    delay(1) {

        count += 1

    }

}

but this doesn't work as it only delays code in brackets. How do I delay the actual loop? I would like the delay to stop from iterating until the time has passed, and then the loop/code can repeat again.

George_E -old
  • 188
  • 1
  • 3
  • 17
  • 1
    Possible duplicate of [How to create a delay in Swift?](https://stackoverflow.com/questions/27517632/how-to-create-a-delay-in-swift) – GIJOW Mar 19 '18 at 18:57
  • 3
    Your delay function has an asynchronous dispatch, so it doesn't block the current thread (which would be bad anyway). It is better to use a `Timer` – Paulw11 Mar 19 '18 at 18:58

2 Answers2

15

Your current code doesn't work because you are doing the increment asynchronously. This means that the for loop will still run at its normal speed.

To achieve what you want, you can use a timer like this:

var count = 0
let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true){ _ in
    count += 1
    print(count)
}

If you want it to stop after 5 times, do this:

var count = 0
var timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true){ t in
    count += 1
    print(count)
    if count >= 5 {
        t.invalidate()
    }
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
4

As @Paulw11 and @Sweeper have suggested, you can use a Timer to do this. However, if the code does need to be asynchronous for some reason, you can reimplement the loop asynchronously by making it recursive:

func loop(times: Int) {
    var i = 0

    func nextIteration() {
        if i < times {
            print("i is \(i)")

            i += 1

            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
                nextIteration()
            }
        }
    }

    nextIteration()
}
Charles Srstka
  • 16,665
  • 3
  • 34
  • 60