How to Create a Delay in Swift: 5 Proven Ways

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

"Wait a second": why delays in Swift are magic, not hacks

\n\n

Imagine: you're writing a pizza ordering app. The user clicks "Pay", and instantly — bam! — the money is deducted. No animation, no pause, no feeling that "something is happening." The user gets scared, closes the app, and you lose a customer. Delay in Swift is not a crutch, but a tool for UX design and proper architecture.

\n\n

The question "How to create a delay in Swift?" on Stack Overflow has gathered tens of thousands of views. And it's no wonder: beginners try to use sleep() (spoiler: you can't do that), while pros look for elegant solutions. We'll break down 5 working methods — from classic GCD to modern async/await. Let's go!

\n\n

1. The Classic: DispatchQueue.main.asyncAfter (iOS 4+)

\n

The most popular way to create a delay in Swift is DispatchQueue.main.asyncAfter. It works on any iOS version and requires no additional imports. It's suitable for executing code on the main thread (e.g., updating the UI).

\n\n
import UIKit\n\nclass ViewController: UIViewController {\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // 2-second delay\n        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n            print("2 seconds have passed!")\n            self.showAlert()\n        }\n    }\n    \n    func showAlert() {\n        let alert = UIAlertController(title: "Hello!", message: "This is a delay", preferredStyle: .alert)\n        alert.addAction(UIAlertAction(title: "OK", style: .default))\n        present(alert, animated: true)\n    }\n}
\n\n

Pros and Cons

\n
    \n
  • Pros: simplicity, backward compatibility, works on the main thread.
  • \n
  • Cons: cannot cancel the delay (unless you save the DispatchWorkItem).
  • \n
\n\n

2. Cancellable Delay via DispatchWorkItem

\n

Sometimes you need to cancel a delay — for example, if the user leaves the screen. DispatchWorkItem solves this problem. Save a reference to the "work" and call cancel().

\n\n
class DelayedTask {\n    private var workItem: DispatchWorkItem?\n    \n    func scheduleDelayedAction() {\n        // Create the task\n        let item = DispatchWorkItem { [weak self] in\n            print("Task executed after delay")\n            self?.doSomething()\n        }\n        \n        // Save and execute\n        workItem = item\n        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: item)\n    }\n    \n    func cancelDelayedAction() {\n        workItem?.cancel()\n        workItem = nil\n        print("Task cancelled")\n    }\n    \n    func doSomething() {\n        // Your code\n    }\n}\n\n// Usage\nlet task = DelayedTask()\ntask.scheduleDelayedAction()\n// Cancel after 1 second\nDispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {\n    task.cancelDelayedAction()\n}
\n\n

Note the [weak self] — this is mandatory to avoid memory leaks in Swift. The delay can outlive the controller if you don't weaken the reference.

\n\n

3. Timer.scheduledTimer: Delay with Repetition

\n

Swift timers are not just for repeating tasks. You can create a one-shot timer with a delay. Plus: the timer is easy to cancel and can be paused.

\n\n
class TimerExample {\n    var timer: Timer?\n    \n    func startDelayedAction() {\n        // One-shot timer after 1.5 seconds\n        timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in\n            print("Timer fired after 1.5 sec")\n            self?.updateUI()\n        }\n    }\n    \n    func stopTimer() {\n        timer?.invalidate()\n        timer = nil\n    }\n    \n    func updateUI() {\n        // Update the interface\n    }\n}
\n\n

When to use Timer

\n