viewDidDisappear : essence de la méthode, cycle de vie d’UIViewController et moment d’appel

Auteur : IT Sectr Publié le : 2026-03-05 Temps de lecture : 9 min

viewDidDisappear est une méthode du cycle de vie d’UIViewController qui est appelée immédiatement après la disparition complète de la vue de l’écran de l’appareil iOS. Les développeurs l’utilisent pour arrêter les animations, libérer de la RAM, se désabonner des notifications et sauvegarder l’état actuel. Selon Apple Developer Documentation (2025), une implémentation correcte de cette méthode prévient jusqu’à 40% des fuites mémoire dans les applications avec navigation active. Sans elle, les processus en arrière-plan peuvent continuer à s’exécuter, consommant des ressources de batterie et de CPU. L’utilisation correcte de viewDidDisappear est l’une des compétences clés d’un développeur iOS, affectant directement les performances et la stabilité de l’application.

Points essentiels

  • viewDidDisappear — la méthode finale du cycle de vie appelée après la disparition de la vue de l’écran
  • Utilisée pour libérer des ressources : arrêt des minuteurs, masquage des indicateurs de chargement
  • Nécessaire pour se désabonner du NotificationCenter et des observations KVO pour éviter les fuites
  • Se distingue de viewWillDisappear par le fait qu’elle est appelée après la fin de l’animation de transition
  • Ne remplace pas deinit — deinit est responsable de la destruction finale de l’objet

Qu’est-ce que viewDidDisappear ?

viewDidDisappear est une méthode hook de la superclasse UIViewController que le système appelle après que la vue a été complètement retirée de la hiérarchie des fenêtres à l’écran. Elle fait partie du cycle de vie standard de la vue dans UIKit et fournit au développeur un point pour effectuer des opérations de finalisation.

La méthode est déclarée dans le protocole UIViewController et est disponible pour être redéfinie dans toutes les sous-classes. La signature de la méthode est : override func viewDidDisappear(_ animated: Bool). Le paramètre animated indique si la transition était accompagnée d’animation. Cela permet de distinguer les transitions programmatiques des transitions animées pour un contrôle plus précis du comportement.

Contrairement à viewWillDisappear, qui est appelée avant le début de l’animation, viewDidDisappear garantit que la vue n’est plus visible pour l’utilisateur. Ceci est critique pour les opérations qui ne doivent être exécutées qu’après que l’interface est complètement masquée — par exemple, masquer des éléments de superposition en plein écran ou terminer l’enregistrement vidéo.

Signature et déclaration

La méthode est définie dans la classe de base UIViewController et a la signature suivante :

swift
import UIKit

class MyViewController: UIViewController {
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // Libérer les ressources et se désabonner
    }
}

L’appel obligatoire à super.viewDidDisappear(animated) dans la première ligne de l’implémentation est une exigence d’UIKit. Sans lui, la superclasse ne peut pas terminer correctement les processus internes liés à l’affichage de la vue. Ignorer cette règle conduit à un comportement de navigation imprévisible et à des plantages potentiels.

Place de viewDidDisappear dans le cycle de vie d’UIViewController

Le cycle de vie complet d’UIViewController se compose de six méthodes clés, chacune responsable d’une phase spécifique de l’existence de la vue. viewDidDisappear termine la séquence de disparition, en suivant viewWillDisappear. Il est important de comprendre l’ordre d’appel de toutes les méthodes pour répartir correctement l’initialisation et la libération des ressources.

La séquence lors de l’apparition de la vue : viewDidLoadviewWillAppearviewDidAppear. Lors du masquage : viewWillDisappearviewDidDisappear. La phase finale — deinit, qui est appelée lorsque l’objet UIViewController est détruit. Ces six méthodes forment un cycle complet garantissant une gestion d’état prévisible.

MéthodeMoment d’appelUtilisation typique
viewDidLoadAprès le chargement de la vue en mémoireConfiguration initiale de l’interface, abonnement aux données
viewWillAppearAvant l’apparition de la vue à l’écranMise à jour des données avant affichage
viewDidAppearAprès l’apparition de la vue à l’écranDémarrage des animations, début d’observation
viewWillDisappearAvant la disparition de la vueSauvegarde des données saisies, annulation des opérations
viewDidDisappearAprès la disparition de la vueLibération des ressources, désabonnement des notifications
deinitLorsque l’objet est détruitNettoyage final, libération des références fortes

Chacune de ces méthodes est appelée exactement une fois par transition correspondante. Une exception est viewDidLoad, qui peut être appelé à nouveau si le ViewController a été déchargé de la mémoire par manque de ressources puis restauré. Dans ce cas, viewDidDisappear précède le viewDidLoad répété.

Relation avec l’animation de transition

Le paramètre animated dans la signature de la méthode indique si la transition était animée. Ceci est utile pour distinguer les transitions programmatiques sans animation (par exemple, lors de la définition de rootViewController) des transitions animées initiées par l’utilisateur. Si la valeur est false, le contrôleur a peut-être été masqué de force par le système — dans ce cas, certaines opérations dépendantes du temps peuvent ne pas être pertinentes.

Quand viewDidDisappear est-elle appelée

Le système appelle viewDidDisappear dans exactement deux scénarios : lorsqu’un ViewController est supprimé de la pile de navigation et lorsqu’il est recouvert par un autre contrôleur. Dans les deux cas, la méthode signale que la vue n’est plus visible pour l’utilisateur et le développeur doit libérer les ressources qui ne sont pas nécessaires en arrière-plan. Comprendre ces scénarios évite les hypothèses erronées sur l’état de l’application.

Le premier scénario — pop depuis UINavigationController. Lorsque l’utilisateur appuie sur le bouton de retour, popViewController:animated est appelé. Le contrôleur actuel reçoit viewDidDisappear, puis, s’il n’y a plus de références fortes vers lui, deinit. Le deuxième scénario — present/dismiss. Lorsqu’un nouveau contrôleur est présenté modalement, le presentingViewController reçoit viewDidDisappear. Lors du dismiss, cette méthode est appelée sur le contrôleur qui a été présenté modalement.

Le troisième scénario, moins évident — ajout d’un child ViewController. Si un nouveau contrôleur enfant est ajouté à un contrôleur conteneur (par exemple, UIPageViewController ou UITabBarController), le contrôleur enfant actif reçoit viewDidDisappear. Ceci est crucial pour les applications avec des onglets ou des carrousels de pages — chaque changement d’onglet doit suspendre correctement le travail de l’écran inactif.

Exceptions et cas non évidents

Il existe une exception importante : si un UIViewController est affiché dans une fenêtre modale et que l’utilisateur le ferme de manière interactive en balayant vers le bas, le système peut ne pas appeler viewDidDisappear si le geste n’est pas terminé. Ce comportement est apparu dans iOS 13 avec le dismiss interactif. Les développeurs doivent gérer l’état via UIAdaptivePresentationControllerDelegate et la méthode didDismiss pour garantir la réception de l’événement.

Une autre particularité — avertissements de mémoire. Lorsque la mémoire est faible, le système peut décharger la vue d’un contrôleur qui n’est pas visible à l’écran. Dans ce cas, viewDidDisappear est généralement appelée avant le déchargement, mais le développeur doit dupliquer les opérations de nettoyage critiques dans didReceiveMemoryWarning comme filet de sécurité. Cette approche évite la perte de données dans des scénarios extrêmes.

Cas d’utilisation typiques

viewDidDisappear est utilisée pour trois catégories principales d’opérations : arrêt des activités, libération des ressources et sauvegarde de l’état. Chaque catégorie a ses propres bonnes pratiques développées par la communauté des développeurs iOS. Examinons les scénarios les plus courants avec des exemples d’implémentation.

  • Arrêt des animations — appel de layer.removeAllAnimations() pour CALayer, arrêt des blocs UIView.animate
  • Libération des ressources — mise à zéro des grandes images, vidage des données en cache, fermeture des descripteurs de fichiers
  • Désabonnement des notifications — suppression des observateurs de NotificationCenter.default, arrêt des observations KVO
  • Sauvegarde de la progression — écrire des brouillons dans CoreData ou UserDefaults lors de la fermeture de l’écran d’édition
  • Masquage des superpositions — suppression des indicateurs de chargement, des infobulles et des éléments popover qui ne doivent pas rester après une transition

Exemple : désabonnement du NotificationCenter

Une erreur typique est de s’abonner aux notifications dans viewDidLoad et de ne jamais se désabonner. Cela provoque l’appel du gestionnaire sur un objet désalloué, entraînant un plantage. L’approche correcte consiste à s’abonner dans viewWillAppear et à se désabonner dans viewDidDisappear, ce qui garantit que l’abonnement n’est actif que lorsque le contrôleur est affiché à l’écran.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleKeyboardShow),
        name: UIResponder.keyboardWillShowNotification,
        object: nil
    )
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

Ce motif garantit que le gestionnaire de notifications n’est actif que lorsque le contrôleur est visible à l’écran. Lors de la navigation vers un autre écran, tous les abonnements sont automatiquement supprimés et restaurés au retour. Cela augmente la fiabilité de l’application et élimine une classe de bogues liés aux notifications.

Exemples de code Swift

Examinons deux exemples pratiques d’utilisation de viewDidDisappear dans des projets réels. Le premier exemple montre l’arrêt d’un minuteur lors du masquage de l’écran, le second montre la fin correcte de l’observation du clavier. Les deux exemples suivent le principe de libération des ressources lorsque le contrôleur est inactif.

Arrêt d’un minuteur

Si un Timer s’exécute à l’écran pour mettre à jour l’interface (par exemple, un compte à rebours ou un carrousel), il doit être arrêté lorsque le contrôleur est masqué. Continuer le minuteur en arrière-plan consomme non seulement des ressources CPU, mais peut aussi provoquer une exception en tentant de mettre à jour une interface invisible.

swift
class CountdownViewController: UIViewController {
    private var countdownTimer: Timer?
    private var remainingSeconds: Int = 60

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        startTimer()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        invalidateTimer()
    }

    private func invalidateTimer() {
        countdownTimer()?.invalidate()
        countdownTimer = nil
    }
}

Mise en pause de la vidéo lors du masquage

Dans de nombreuses applications, un AVPlayer lit une vidéo dans un lecteur intégré. Si l’utilisateur navigue vers un autre écran, la vidéo doit être automatiquement mise en pause. Implémenter cela dans viewDidDisappear garantit que la pause a lieu après que l’écran est complètement masqué — cela évite le scintillement d’une image noire pendant la transition.

swift
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if player().timeControlStatus == .playing {
        player().pause()
        playerLayer().removeFromSuperlayer()
    }
    player = nil
}

La mise à zéro de la variable player après la pause libère supplémentairement la mémoire occupée par les tampons vidéo. Cette approche est particulièrement importante pour les applications avec de longues vidéos, où le tampon peut occuper des dizaines de mégaoctets. Combiner la pause avec la mise à zéro des références minimise l’empreinte de l’application en arrière-plan.

viewDidDisappear et les autres méthodes du cycle de vie

viewDidDisappear est souvent confondue avec viewWillDisappear et deinit, mais chacune de ces méthodes a son propre domaine de responsabilité. Comprendre les limites entre elles est la clé d’une architecture d’application iOS stable. Une utilisation incorrecte peut entraîner une double libération de ressources ou, au contraire, des fuites de ressources.

La principale différence entre viewDidDisappear et viewWillDisappear est le moment de l’appel. viewWillDisappear est appelée lorsque la vue est encore visible mais se prépare à disparaître. Cela convient pour sauvegarder les données visibles (texte dans les champs de saisie). viewDidDisappear est appelée après la fin de l’animation, lorsque la vue n’est plus visible — idéale pour libérer les ressources non liées à l’état visuel.

deinit, contrairement à viewDidDisappear, n’est appelé que lorsque l’objet UIViewController est détruit en mémoire. Si le contrôleur est simplement masqué (par exemple, recouvert par une fenêtre modale), deinit n’est pas appelé. Dans cette situation, viewDidDisappear est le seul point pour effectuer des opérations de finalisation. Le nettoyage complet des ressources doit se faire dans deinit, mais viewDidDisappear gère la libération temporaire jusqu’à la prochaine apparition.

Quand utiliser chaque méthode

  • viewWillDisappear — sauvegarde des données saisies, envoi d’analyses sur le début de la transition
  • viewDidDisappear — arrêt des animations, désabonnement des notifications, masquage des éléments de superposition
  • deinit — libération finale des grandes ressources, fermeture des connexions réseau

Lors du développement avec SwiftUI, la méthode viewDidDisappear n’est pas utilisée — elle est remplacée par le modificateur .onDisappear qui fonctionne de manière similaire. Cependant, SwiftUI manque de contrôle direct du cycle de vie, et les développeurs comptent sur Combine et les objets State pour la gestion des ressources. Pour les applications UIKit, viewDidDisappear reste l’outil principal pour gérer la disparition de l’écran.

Erreurs courantes d’implémentation

Même les développeurs iOS expérimentés commettent des erreurs en travaillant avec viewDidDisappear. Examinons les cinq problèmes les plus courants et les moyens de les prévenir. Connaître ces anti-patrons aidera à éviter des bogues difficiles à trouver liés au cycle de vie du contrôleur.

  • Absence de super.viewDidDisappear — l’appel à super est obligatoire pour le bon fonctionnement d’UIKit ; son absence peut perturber l’état interne du contrôleur
  • Opérations lourdes dans viewDidDisappear — l’écriture synchrone de grandes données dans viewDidDisappear bloque le thread principal et dégrade l’animation de transition
  • Désabonnement oublié aux notifications — si removeObserver n’est pas appelé dans viewDidDisappear, le gestionnaire peut se déclencher sur un objet zombie, provoquant EXC_BAD_ACCESS
  • Double désabonnement — la suppression d’un observateur déjà supprimé ailleurs entraîne NSInternalInconsistencyException
  • Dépendance à l’ordre d’appel — dans les conteneurs imbriqués, l’ordre d’appel de viewDidDisappear pour les contrôleurs enfants et parents n’est pas garanti

Une attention particulière doit être accordée à la sécurité des threads. Si viewDidDisappear est appelée sur le thread principal (ce qui est garanti par UIKit), mais que le nettoyage des ressources implique des opérations asynchrones, l’accès aux données partagées doit être synchronisé. Utiliser DispatchQueue.main.async dans viewDidDisappear pour mettre à jour l’interface après l’achèvement d’une tâche asynchrone est une approche courante mais correcte.

Un autre anti-patron important — appel de méthodes déléguées dans viewDidDisappear qui peuvent initier une nouvelle transition ou une présentation modale. Cela crée un cycle où viewDidDisappear peut être appelée à nouveau avant la fin du premier appel. Apple recommande d’éviter les présentations modales dans les méthodes du cycle de vie, en les déplaçant vers des gestionnaires d’événements séparés.

Questions fréquentes

En quoi viewDidDisappear diffère-t-elle de viewWillDisappear ?

viewWillDisappear est appelée avant le début de l’animation de masquage, lorsque la vue est encore visible. viewDidDisappear est appelée après la disparition complète de la vue. Utilisez viewWillDisappear pour sauvegarder les données et viewDidDisappear pour libérer les ressources.

Faut-il appeler super.viewDidDisappear ?

Oui, l’appel à super.viewDidDisappear(animated) est obligatoire. UIKit utilise cette méthode pour les notifications internes et la finalisation de l’état de transition. Sans l’appel à super, UINavigationController et UITabBarController peuvent mal fonctionner.

viewDidDisappear peut-elle ne pas être appelée ?

Oui, avec le dismiss interactif dans iOS 13+ (balayage vers le bas), la méthode peut ne pas être appelée si le geste n’est pas terminé. Pour garantir la réception de l’événement, utilisez le délégué UIAdaptivePresentationControllerDelegate et la méthode presentationControllerDidDismiss.

Quel est le meilleur : viewDidDisappear ou deinit ?

deinit n’est appelé que lors de la destruction de l’objet, tandis que viewDidDisappear est appelée à chaque masquage. Pour libérer des ressources à chaque transition (par exemple, se désabonner des notifications), utilisez viewDidDisappear. Pour le nettoyage final lors de la suppression du contrôleur, utilisez deinit.

Comment viewDidDisappear fonctionne-t-elle dans SwiftUI ?

Dans SwiftUI, au lieu de viewDidDisappear, le modificateur .onDisappear { } est utilisé. Il est appelé lorsque la vue disparaît de la hiérarchie. Contrairement à UIKit, SwiftUI ne garantit pas que onDisappear sera appelé dans tous les scénarios d’animation.

Résumé

  • viewDidDisappear — la dernière méthode du cycle de vie avant le masquage, appelée après la fin de l’animation de transition
  • Objectif principal — libérer des ressources, arrêter les minuteurs et se désabonner des notifications
  • L’appel à super.viewDidDisappear est obligatoire pour le bon fonctionnement d’UIKit
  • Se distingue de viewWillDisappear par le moment d’appel : après l’animation, pas avant
  • Ne remplace pas deinit — deinit est appelé lors de la destruction de l’objet, viewDidDisappear à chaque masquage
  • Ne pas utiliser pour les opérations synchrones lourdes — elles bloquent le thread principal et perturbent l’animation
  • Dans iOS 13+, un traitement supplémentaire via UIAdaptivePresentationControllerDelegate est nécessaire pour un appel garanti

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi