viewWillDisappear é um método de UIViewController que o UIKit chama logo antes de a tela começar a desaparecer do display do usuário. De acordo com a Apple Developer Documentation, este método recebe um parâmetro animated e é acionado em push, pop, present, dismiss e troca de abas. viewWillDisappear é o local principal para salvar o estado e liberar recursos corretamente.
Principais Pontos
viewWillDisappear é um método de UIViewController que o UIKit chama logo antes de a View do controlador começar a desaparecer da tela. Neste momento a tela ainda está visível para o usuário, mas a transição já foi iniciada: NavigationController começou a animação push/pop, a view modal começou a fechar, ou TabBar começou a alternar para outra aba. O desenvolvedor sobrescreve este método para realizar operações que exigem que a tela ainda esteja acessível, mas esteja se preparando para ocultar.
Ao contrário do viewDidDisappear, que é acionado após a tela estar oculta, o viewWillDisappear fornece a última oportunidade para salvar dados e liberar recursos enquanto o usuário ainda pode ver a interface. Isso é extremamente importante para a UX — salvar um rascunho ou parar um temporizador deve acontecer antes que o usuário mude para outra tela.
O método aceita um parâmetro animated, que indica se o desaparecimento é animado. Um valor true significa que o UIKit está realizando uma transição animada, false significa que a tela desaparece instantaneamente, por exemplo durante um dismiss sem animação ou remoção programática da hierarquia.
viewWillDisappear é chamado em todos os cenários onde a tela atual deixa de estar ativa. Vamos rever os principais casos específicos do desenvolvimento iOS.
Quando UINavigationController faz push de um novo controlador, viewWillDisappear é chamado no atual no início da animação de transição. Neste momento a tela atual ainda está visível sob o novo controlador deslizando sobre ela. Este é o cenário padrão onde viewWillDisappear é acionado com animated = true.
Quando o usuário toca o botão voltar ou faz um deslize interativo para trás, viewWillDisappear é chamado no controlador atual. Com um gesto interativo esta chamada pode ser cancelada se o usuário mudar de ideia e devolver a tela ao seu lugar. Esta é uma característica importante a considerar ao projetar o salvamento de estado.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
saveDraftData()
NotificationCenter.default.removeObserver(self)
}
Ao fechar uma view modal, viewWillDisappear é chamado no controlador que está sendo fechado no início da animação de dismiss. Neste ponto você pode passar resultados de volta através de um delegate ou closure, já que o controlador que apresentou a modal ainda não retomou o controle.
UITabBarController chama viewWillDisappear no controlador da aba que está sendo abandonada logo após o usuário tocar em outra aba. Se a aba atual tiver processos ativos — reprodução de mídia, download de arquivo, temporizador — eles devem ser pausados ou interrompidos aqui.
viewWillDisappear resolve tarefas específicas de gerenciamento de recursos e estado. Vamos rever os cenários principais com exemplos de código.
A tarefa mais importante do viewWillDisappear é salvar os dados que o usuário inseriu ou modificou na tela atual. Rascunhos de mensagens, campos de formulário editados, configurações selecionadas — tudo isso deve ser salvo antes que a tela desapareça. Use Core Data, UserDefaults ou armazenamento de arquivos para persistência.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
guard hasUnsavedChanges else { return }
draftStorage.save(currentDraft)
}
NotificationCenter, KVO e publishers do Combine aos quais você se inscreveu em viewWillAppear ou viewDidLoad devem ser cancelados em viewWillDisappear. Se não o fizer, as notificações chegarão à tela oculta, causando atualizações de interface que o usuário não vê, ou — pior — falhas devido ao acesso a objetos já desalocados.
Animações UIView iniciadas em viewDidAppear e temporizadores rodando via Timer ou DispatchSource devem ser parados em viewWillDisappear. Animações contínuas em uma tela oculta desperdiçam GPU e bateria sem nenhum benefício para o usuário. Pare-os explicitamente chamando invalidate nos temporizadores e removeAllAnimations nas camadas.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
countdownTimer?.invalidate()
countdownTimer = nil
loadingIndicator.layer.removeAllAnimations()
}
Se um controlador foi aberto para obter um resultado — selecionar um item, inserir texto, confirmar uma ação — viewWillDisappear é o último momento em que o controlador original ainda existe na pilha e pode receber dados. Chame o delegate ou closure antes de deinit ser invocado.
O salvamento confiável de estado é uma das tarefas mais desafiadoras no desenvolvimento iOS. viewWillDisappear é um elemento importante, mas não o único da estratégia. Vamos ver uma abordagem abrangente.
Nível 1 — salvamento em viewWillDisappear. Salvamento rápido de dados leves que devem estar disponíveis imediatamente ao retornar. Adequado para estado da UI: posição de rolagem, segmento selecionado, texto em campos de entrada. Problema: em um gesto de pop interativo cancelado, o salvamento ocorre mesmo que o usuário tenha permanecido na tela — os dados são sobrescritos desnecessariamente.
Nível 2 — salvamento em viewDidDisappear. Duplica o salvamento do primeiro nível, mas é acionado apenas após a tela estar garantidamente oculta. Esta é uma proteção contra gestos cancelados. No entanto, se você já cancelou a assinatura de notificações em viewWillDisappear, viewDidDisappear pode não ter acesso a alguns dados.
Nível 3 — salvamento via notificações do aplicativo. UIApplication.willResignActiveNotification e UIApplication.didEnterBackgroundNotification capturam a minimização do aplicativo. Se o usuário minimizou o aplicativo, viewWillDisappear pode não ter sido chamado — mas o salvamento através destas notificações garante a integridade dos dados no final da sessão.
| Nível | Método/Notificação | Confiabilidade | Uso |
|---|---|---|---|
| 1 | viewWillDisappear | Alta | Estado da UI, rascunhos |
| 2 | viewDidDisappear | Muito alta | Dados críticos |
| 3 | willResignActive | Máxima | Ao minimizar o app |
Recomendação: use uma combinação dos três níveis para dados críticos do usuário. Para estado não crítico, o primeiro nível é suficiente. É importante não salvar os mesmos dados várias vezes — use um flag dirty indicando que os dados mudaram desde o último salvamento.
Atenção especial deve ser dada à estratégia para telas CRUD onde o usuário insere dados. Nessas telas não é recomendado salvar cada tecla pressionada em viewWillDisappear — isso é excessivo. Use auto-salvamento com atraso (debounce) via Timer, e use viewWillDisappear apenas para o salvamento forçado final se houver alterações não salvas. Esta abordagem equilibra desempenho e integridade dos dados.
Para aplicativos que usam Core Data, uma medida adicional é chamar saveContext em viewWillDisappear apenas quando houver alterações reais no contexto de objetos gerenciados. Verificar context.hasChanges antes de salvar evita gravações desnecessárias no armazenamento persistente e prolonga a vida útil da bateria do dispositivo. Combine esta verificação com o salvamento global em applicationDidEnterBackground.
O uso incorreto do viewWillDisappear pode levar à perda de dados, vazamentos de memória e comportamento instável do aplicativo. Vamos rever erros frequentes de desenvolvedores iOS.
Primeiro erro — salvar dados apenas em viewWillDisappear. Como discutido acima, com um gesto de pop interativo o método é chamado mesmo que a tela não tenha desaparecido. Se o salvamento tiver efeitos colaterais — enviar dados para o servidor, alterar o estado — isso pode levar a falsos disparos. Adicione uma verificação de isBeingDismissed ou isMovingFromParent.
Segundo erro — não cancelar a assinatura do NotificationCenter. Este é um dos vazamentos de memória mais comuns no iOS. Se você se inscreveu em viewWillAppear para UIResponder.keyboardWillShowNotification mas não cancelou em viewWillDisappear, o closure continuará sendo chamado. Ao fazer deinit do controlador, o closure fará referência a um objeto desalocado — falha do aplicativo garantida.
Terceiro erro — realizar operações síncronas pesadas. Salvar grandes quantidades de dados, gravar em Core Data ou no sistema de arquivos em viewWillDisappear bloqueia a thread principal. Se a operação durar mais que a animação de transição, o UIKit pausa a thread e a interface congela. Transfira salvamentos pesados para filas em segundo plano.
Quarto erro — esquecer de chamar super. Não chamar super.viewWillDisappear pode quebrar UINavigationController e UITabBarController, que usam este método para seus estados internos. Sempre chame super primeiro ou por último, seguindo a documentação da Apple.
Este problema é agravado no iOS com multitarefa ativa e alternância entre aplicativos. Quinto erro — usar DispatchQueue.main.async após salvar em viewWillDisappear. Se você enviar assincronamente um bloco para a fila principal após chamar super.viewWillDisappear, não há garantia de que o controlador ainda exista no momento da execução do bloco. Sempre use referências fracas [weak self] dentro dos closures para evitar acessar memória desalocada e evitar falhas do aplicativo.
Perguntas Frequentes
viewWillDisappear é chamado no início do desaparecimento quando a tela ainda está visível. viewDidDisappear é chamado após a tela estar completamente oculta e a animação ter terminado.
Use viewDidDisappear para confirmar o salvamento ou verifique as propriedades isMovingFromParent e isBeingDismissed dentro de viewWillDisappear para determinar se a tela realmente desaparecerá.
Sim, absolutamente se você usa blocos ou seletores com self. O ARC não gerencia assinaturas do NotificationCenter. No iOS 9+ para blocos use uma referência fraca e cancele a assinatura em viewWillDisappear.
De forma alguma — force quit não chama métodos do ciclo de vida. Para salvamento garantido no encerramento do aplicativo, use UIApplication.willTerminateNotification ou salve os dados em tempo real à medida que mudam.
Sim, em um gesto de pop interativo o UIKit chama viewWillDisappear logo após o início do gesto. Se o usuário cancelar o gesto, a tela permanece visível mas o método já foi acionado. Sempre verifique isMovingFromParent.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também