To add a delay to your code we need to use GCD . GCD has a built in method called asyncAfter , which will allow us to run code after a given amount of time. In the above code, Before delay will be printed out first and after 2 seconds, Async after 2 seconds will be printed.
Execute Code After Delay Using asyncAfter() Sometimes, you might hit the requirement to perform some code execution after a delay, and you can do this by using Swift GCD (Grand Central Dispatch) system to execute some code after a set delay.
dispatch_after()
is the standard way of delaying actions.
indicator.startAnimating()
let delay = 4.5 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue()) {
indicator.stopAnimating()
}
See: dispatch_after - GCD in swift?
Update for Swift 3.0
indicator.startAnimating()
let delay = Int(4.5 * Double(1000))
DispatchQueue.main.after(when: .now() + .milliseconds(delay)) {
indicator.stopAnimating()
}
However, in the spirit of Swift 3.0, I think extending DispatchQueue
would be a better solution.
extension DispatchQueue {
func delay(_ timeInterval: TimeInterval, execute work: () -> Void) {
let milliseconds = Int(timeInterval * Double(1000))
after(when: .now() + .milliseconds(milliseconds), execute: work)
}
}
This leaves us with a very nice
indicator.startAnimating()
DispatchQueue.main.delay(4.5) {
indicator.stopAnimating()
}
Update 2
Digging into the Xcode 8.0 beta, I found public func +(time: DispatchTime, seconds: Double) -> DispatchTime
. So, I guess this is valid…
indicator.startAnimating()
DispatchQueue.main.after(when: .now() + 4.5) {
indicator.stopAnimating()
}
I don't think there is a need to extend DispatchQueue
for something this clean already.
--
Update for Swift 3.1
There is new syntax for Swift 3.1. They just likes to change things don't they.
indicator.startAnimating()
DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
indicator.stopAnimating()
}
With the updated Swift 3 syntax this becomes
DispatchQueue.main.asyncAfter(deadline: .now() + 4.5) {
indicator.stopAnimating()
}
Here is a cleaner and more expressive code to do this using Swift 3.1 and Grand Central Dispatch:
Swift 3.1:
indicator.startAnimating()
// Runs after 1 second on the main queue.
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) {
indicator.stopAnimating()
}
Also .seconds(Int)
, .microseconds(Int)
and .nanoseconds(Int)
may be used for the time.
New in iOS 10, Timer has a block initializer that executes on the main thread. Its also slightly more flexible because you can take a reference to the Timer and cancel it or reschedule it after the fact.
let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) {_ in
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With