Como criar um atraso em Swift: 5 maneiras comprovadas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

"Espere um segundo": por que atrasos em Swift são mágica, não gambiarras

\n\n

Imagine: você está escrevendo um aplicativo para pedir pizza. O usuário clica em "Pagar" e instantaneamente — bum! — o dinheiro é debitado. Sem animação, sem pausa, sem a sensação de "algo está acontecendo". O usuário se assusta, fecha o aplicativo, e você perde um cliente. Atraso em Swift não é uma muleta, mas uma ferramenta de design de UX e arquitetura adequada.

\n\n

A pergunta "How to create a delay in Swift?" no Stack Overflow acumulou dezenas de milhares de visualizações. E não é surpresa: iniciantes tentam usar sleep() (spoiler: não pode), enquanto profissionais buscam soluções elegantes. Vamos analisar 5 maneiras funcionais — desde o clássico GCD até o moderno async/await. Vamos lá!

\n\n

1. Clássico: DispatchQueue.main.asyncAfter (iOS 4+)

\n

A maneira mais popular de criar um atraso em Swift é DispatchQueue.main.asyncAfter. Funciona em qualquer versão do iOS e não requer imports adicionais. É adequado para executar código na thread principal (por exemplo, atualizar a UI).

\n\n
import UIKit\n\nclass ViewController: UIViewController {\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // Atraso de 2 segundos\n        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n            print("2 segundos se passaram!")\n            self.showAlert()\n        }\n    }\n    \n    func showAlert() {\n        let alert = UIAlertController(title: "Olá!", message: "Isso é um atraso", preferredStyle: .alert)\n        alert.addAction(UIAlertAction(title: "OK", style: .default))\n        present(alert, animated: true)\n    }\n}
\n\n

Prós e contras

\n
    \n
  • Prós: simplicidade, compatibilidade reversa, funciona na thread principal.
  • \n
  • Contras: não é possível cancelar o atraso (a menos que você salve o DispatchWorkItem).
  • \n
\n\n

2. Atraso cancelável via DispatchWorkItem

\n

Às vezes é necessário cancelar um atraso — por exemplo, se o usuário saiu da tela. DispatchWorkItem resolve esse problema. Salvamos uma referência ao "trabalho" e chamamos cancel().

\n\n
class DelayedTask {\n    private var workItem: DispatchWorkItem?\n    \n    func scheduleDelayedAction() {\n        // Criando a tarefa\n        let item = DispatchWorkItem { [weak self] in\n            print("Tarefa executada após o atraso")\n            self?.doSomething()\n        }\n        \n        // Salvando e executando\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("Tarefa cancelada")\n    }\n    \n    func doSomething() {\n        // Seu código\n    }\n}\n\n// Uso\nlet task = DelayedTask()\ntask.scheduleDelayedAction()\n// Cancelando após 1 segundo\nDispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {\n    task.cancelDelayedAction()\n}
\n\n

Observe o [weak self] — isso é obrigatório para evitar vazamentos de memória em Swift. O atraso pode sobreviver ao controlador se a referência não for enfraquecida.

\n\n

3. Timer.scheduledTimer: atraso com repetição

\n

Timers em Swift não são apenas para tarefas repetitivas. Você pode criar um timer de uso único com atraso. Vantagem: o timer é facilmente cancelado e pode ser pausado.

\n\n
class TimerExample {\n    var timer: Timer?\n    \n    func startDelayedAction() {\n        // Timer de uso único após 1.5 segundos\n        timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in\n            print("Timer disparou após 1.5 seg")\n            self?.updateUI()\n        }\n    }\n    \n    func stopTimer() {\n        timer?.invalidate()\n        timer = nil\n    }\n    \n    func updateUI() {\n        // Atualizando a interface\n    }\n}
\n\n

Quando usar Timer

\n