In earlier versions of Swift, one could create a delay with the following code:
let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
//put your code which should be executed with a delay here
}
But now, in Swift 3, Xcode automatically changes 6 different things but then the following error appears: "Cannot convert DispatchTime.now
to expected value dispatch_time_t
aka UInt64
."
How can one create a delay before running a sequence of code in Swift 3?
After a lot of research, I finally figured this one out.
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds.
// Code you want to be delayed
}
This creates the desired "wait" effect in Swift 3 and Swift 4.
Inspired by a part of this answer.
I like one-line notation for GCD, it's more elegant:
DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) {
// do stuff 42 seconds later
}
Also, in iOS 10 we have new Timer methods, e.g. block initializer:
(so delayed action may be canceled)
let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in
// do stuff 42 seconds later
}
Btw, keep in mind: by default, timer is added to the default run loop mode. It means timer may be frozen when the user is interacting with the UI of your app (for example, when scrolling a UIScrollView) You can solve this issue by adding the timer to the specific run loop mode:
RunLoop.current.add(timer, forMode: .common)
At this blog post you can find more details.
Try the following function implemented in Swift 3.0 and above
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
Usage
delayWithSeconds(1) {
//Do something
}
Try the below code for delay
//MARK: First Way
func delayForWork() {
delay(3.0) {
print("delay for 3.0 second")
}
}
delayForWork()
// MARK: Second Way
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
// your code here delayed by 0.5 seconds
}
One way is to use DispatchQueue.main.asyncAfter
as a lot of people have answered.
Another way is to use perform(_:with:afterDelay:)
. More details here
perform(#selector(delayedFunc), with: nil, afterDelay: 3)
@IBAction func delayedFunc() {
// implement code
}
Most common things to use are asyncAfter()
and Timer
. But if blocking thread is OK, then there is an option:
sleep(3) // in seconds
usleep // in 1/million of second
For asynchronous programming (Swift 5.5) pausing in func looks like this:
func someAsyncFunc() async {
await Task.sleep(2_000_000_000) // Two seconds
// Code to be executed with a delay here
}
//Runs function after x seconds
public static func runThisAfterDelay(seconds: Double, after: @escaping () -> Void) {
runThisAfterDelay(seconds: seconds, queue: DispatchQueue.main, after: after)
}
public static func runThisAfterDelay(seconds: Double, queue: DispatchQueue, after: @escaping () -> Void) {
let time = DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)
queue.asyncAfter(deadline: time, execute: after)
}
//Use:-
runThisAfterDelay(seconds: x){
//write your code here
}
Success story sharing
DispatchQueue.main.asyncAfter(deadline: when)