viewDidDisappear — is een levenscyclusmethode van UIViewController die onmiddellijk wordt aangeroepen nadat de weergave (view) volledig van het scherm van een iOS-apparaat is verdwenen. Ontwikkelaars gebruiken het om animaties te stoppen, RAM-geheugen vrij te maken, zich uit te schrijven voor meldingen en de huidige status op te slaan. Volgens Apple Developer Documentation (2025) voorkomt een correcte implementatie van deze methode tot 40% van geheugenlekken in applicaties met actieve navigatie. Zonder dit kunnen achtergrondprocessen blijven draaien, wat batterij- en processorbronnen verbruikt. Correct gebruik van viewDidDisappear is een van de belangrijkste vaardigheden van een iOS-ontwikkelaar en heeft direct invloed op de prestaties en stabiliteit van de applicatie.
Belangrijkste punten
viewDidDisappear — is een hook-methode van de superklasse UIViewController die het systeem aanroept nadat de weergave (view) volledig uit de vensterhiërarchie op het scherm is verwijderd. Het maakt deel uit van de standaard levenscyclus van een view in UIKit en biedt de ontwikkelaar een punt voor het uitvoeren van afsluitende operaties.
De methode is gedeclareerd in het UIViewController-protocol en is beschikbaar voor overschrijving in alle subklassen. De signatuur van de methode: override func viewDidDisappear(_ animated: Bool). De parameter animated geeft aan of de overgang gepaard ging met een animatie. Dit maakt het mogelijk om programmatische en geanimeerde overgangen te onderscheiden voor een preciezere controle van het gedrag.
In tegenstelling tot viewWillDisappear, dat wordt aangeroepen voor het begin van de animatie, garandeert viewDidDisappear dat de view niet meer zichtbaar is voor de gebruiker. Dit is kritisch voor operaties die pas mogen worden uitgevoerd nadat de interface volledig is verborgen — bijvoorbeeld het verbergen van volledige-scherm overlay-elementen of het beëindigen van video-opname.
De methode is gedefinieerd in de basisklasse UIViewController en heeft de volgende signatuur:
import UIKit
class MyViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Vrijmaken van bronnen en uitschrijven
}
}
De verplichte aanroep van super.viewDidDisappear(animated) in de eerste regel van de implementatie — dit is een vereiste van UIKit. Zonder dit kan de superklasse de interne processen met betrekking tot het tonen van de view niet correct voltooien. Het negeren van deze regel leidt tot onvoorspelbaar navigatiegedrag en mogelijke crashes.
De volledige levenscyclus van UIViewController bestaat uit zes belangrijke methoden, elk verantwoordelijk voor een specifieke fase van het bestaan van de view. viewDidDisappear voltooit de verbergingssequentie, na viewWillDisappear. Het is belangrijk om de volgorde van aanroepen van alle methoden te begrijpen om initialisatie en vrijgave van bronnen correct te verdelen.
De volgorde bij het verschijnen van de view: viewDidLoad → viewWillAppear → viewDidAppear. Bij verbergen: viewWillDisappear → viewDidDisappear. De laatste fase — deinit, die wordt aangeroepen bij de vernietiging van het UIViewController-object. Deze zes methoden vormen een complete cyclus die voorspelbaar statusbeheer garandeert.
| Methode | Moment van aanroep | Typische toepassing |
|---|---|---|
| viewDidLoad | Na het laden van de view in het geheugen | Initiële UI-configuratie, abonneren op gegevens |
| viewWillAppear | Voor het verschijnen van de view op het scherm | Gegevens bijwerken voor weergave |
| viewDidAppear | Na het verschijnen van de view op het scherm | Starten van animaties, begin van animatie |
| viewWillDisappear | Voor het verdwijnen van de view | Opslaan van ingevoerde gegevens, annuleren van operaties |
| viewDidDisappear | Na het verdwijnen van de view | Vrijmaken van bronnen, uitschrijven voor meldingen |
| deinit | Bij vernietiging van het object | Definitieve opschoning, vrijmaken van sterke verwijzingen |
Elk van deze methoden wordt precies één keer aangeroepen voor de betreffende overgang. Uitzondering — viewDidLoad, dat opnieuw kan worden aangeroepen als de ViewController uit het geheugen is verwijderd door gebrek aan bronnen en vervolgens is hersteld. In dat geval gaat viewDidDisappear vooraf aan een nieuwe viewDidLoad.
De parameter animated in de signatuur van de methode geeft aan of de overgang geanimeerd was. Dit is handig om programmatische overgangen zonder animatie (bijvoorbeeld bij het instellen van rootViewController) te onderscheiden van geanimeerde overgangen die door de gebruiker zijn geïnitieerd. Als de waarde false is, is de controller mogelijk gedwongen verborgen door het systeem — in dat geval kunnen sommige tijdsafhankelijke operaties irrelevant zijn.
Het systeemt roept viewDidDisappear aan in precies twee scenario's: wanneer de ViewController uit de navigatiestapel wordt verwijderd en wanneer deze wordt bedekt door een andere controller. In beide gevallen geeft de methode aan dat de view niet meer zichtbaar is voor de gebruiker en moet de ontwikkelaar bronnen vrijmaken die niet nodig zijn op de achtergrond. Inzicht in deze scenario's voorkomt verkeerde aannames over de status van de applicatie.
Het eerste scenario — pop uit UINavigationController. Wanneer de gebruiker op de knop „Terug” drukt, wordt popViewController: animated aangeroepen. De huidige controller ontvangt viewDidDisappear en vervolgens, als er geen sterke verwijzingen meer naar zijn, deinit. Het tweede scenario — present/dismiss. Bij het modaal tonen van een nieuwe controller ontvangt de presentingController viewDidDisappear. Bij dismiss wordt deze methode aangeroepen bij de controller die modaal werd getoond.
Het derde, minder voor de hand liggende scenario — toevoegen van een child ViewController. Als aan een containercontroller (bijvoorbeeld UIPageViewController of UITabBarController) een nieuwe child-controller wordt toegevoegd, ontvangt de actieve child-controller viewDidDisappear. Dit is kritisch voor apps met tabbladen of paginacarousels — elke tabwissel moet de werking van het inactieve scherm correct onderbreken.
Er is een belangrijke uitzondering: als UIViewController wordt weergegeven in een modaal venster en de gebruiker het interactief sluit door naar beneden te vegen, kan het systeem viewDidDisappear niet aanroepen bij een onvolledige veegbeweging. Dit gedrag verscheen in iOS 13 samen met interactieve dismiss. Ontwikkelaars moeten de status afhandelen via UIAdaptivePresentationControllerDelegate en de methode didDismiss om gegarandeerd de gebeurtenis te ontvangen.
Een ander kenmerk — geheugenwaarschuwingen. Bij geheugentekort kan het systeem de view van een controller die niet op het scherm wordt weergegeven, verwijderen. In dit geval wordt viewDidDisappear meestal aangeroepen voor het verwijderen, maar de ontwikkelaar moet kritisch belangrijke vrijgaveoperaties dupliceren in didReceiveMemoryWarning voor de zekerheid. Een dergelijke aanpak voorkomt gegevensverlies in extreme scenario's.
viewDidDisappear wordt gebruikt voor drie hoofdcategorieën operaties: stoppen van activiteiten, vrijmaken van bronnen en opslaan van status. Elke categorie heeft zijn eigen best practices, ontwikkeld door de gemeenschap van iOS-ontwikkelaars. Laten we de meest voorkomende scenario's bekijken met implementatievoorbeelden.
Een typische fout — abonneren op meldingen in viewDidLoad en nooit uitschrijven. Dit leidt tot het aanroepen van de handler op een vernietigd object, wat een crash veroorzaakt. De juiste aanpak — abonneren in viewWillAppear en uitschrijven in viewDidDisappear, wat garandeert dat het abonnement alleen actief is tijdens het tonen van de controller op het scherm.
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)
}
Dit patroon garandeert dat de meldingenhandler alleen actief is wanneer de controller zichtbaar is op het scherm. Bij het overgaan naar een ander scherm worden alle abonnementen automatisch verwijderd en bij terugkeer hersteld. Dit verhoogt de betrouwbaarheid van de applicatie en elimineert een klasse fouten gerelateerd aan meldingen.
Laten we twee praktische voorbeelden bekijken van het gebruik van viewDidDisappear in echte projecten. Het eerste voorbeeld demonstreert het stoppen van een timer bij het verbergen van het scherm, het tweede — het correct beëindigen van het toetsenbordwaarneming. Beide voorbeelden volgen het principe van het vrijmaken van bronnen bij inactiviteit van de controller.
Als op het scherm een Timer actief is voor het bijwerken van de UI (bijvoorbeeld een aftelling of carrousel), moet deze worden gestopt bij het verbergen van de controller. Het voortzetten van de timer op de achtergrond verbruikt niet alleen processorbronnen, maar kan ook een uitzondering veroorzaken bij het proberen bij te werken van een onzichtbare UI.
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
}
}
In veel applicaties speelt AVPlayer video af in een ingebouwde speler. Als de gebruiker naar een ander scherm gaat, moet de video automatisch worden gepauzeerd. Implementatie in viewDidDisappear garandeert dat de pauze plaatsvindt na volledige verberging van het scherm — dit voorkomt flikkering van een zwart frame bij de overgang.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if player().timeControlStatus == .playing {
player().pause()
playerLayer().removeFromSuperlayer()
}
player = nil
}
Het nullen van de variabele player na de pauze maakt bovendien het geheugen vrij dat door videobuffers wordt ingenomen. Deze aanpak is vooral belangrijk voor applicaties met lange video's, waar de buffer tientallen megabytes kan innemen. Het combineren van pauze met het nullen van verwijzingen minimaliseert de footprint van de applicatie op de achtergrond.
viewDidDisappear wordt vaak verward met viewWillDisappear en deinit, maar elk van deze methoden heeft zijn eigen verantwoordelijkheidsgebied. Het begrijpen van de grenzen ertussen is de sleutel tot een stabiele architectuur van een iOS-applicatie. Onjuist gebruik kan leiden tot dubbele vrijgave van bronnen of, omgekeerd, tot lekkage ervan.
Het belangrijkste verschil tussen viewDidDisappear en viewWillDisappear — het moment van aanroep. viewWillDisappear wordt aangeroepen wanneer de view nog zichtbaar is, maar zich al voorbereidt op verdwijning. Dit is geschikt voor het opslaan van zichtbare gegevens (tekst in invoervelden). viewDidDisappear wordt aangeroepen na voltooiing van de animatie, wanneer de view gegarandeerd niet zichtbaar is — ideaal voor het vrijmaken van bronnen die niet gerelateerd zijn aan de visuele status.
deinit, in tegenstelling tot viewDidDisappear, wordt alleen aangeroepen bij de vernietiging van het UIViewController-object in het geheugen. Als de controller alleen is verborgen (bijvoorbeeld bedekt door een modaal venster), wordt deinit niet aangeroepen. In deze situatie is viewDidDisappear het enige punt voor het uitvoeren van afsluitende operaties. Volledige vrijgave van bronnen moet plaatsvinden in deinit, maar viewDidDisappear is verantwoordelijk voor tijdelijke vrijgave tot herverschijning.
Bij ontwikkeling met SwiftUI wordt de methode viewDidDisappear niet gebruikt — deze wordt vervangen door de modifier .onDisappear, die op vergelijkbare wijze werkt. In SwiftUI is er echter geen directe controle over de levenscyclus en vertrouwen ontwikkelaars op Combine en State-objecten voor resourcebeheer. Voor UIKit-applicaties blijft viewDidDisappear het belangrijkste hulpmiddel voor het beheren van schermverberging.
Zelfs ervaren iOS-ontwikkelaars maken fouten bij het werken met viewDidDisappear. Laten we vijf veelvoorkomende problemen en manieren om ze te voorkomen bekijken. Kennis van deze antipatronen helpt bij het vermijden van moeilijk te traceren bugs gerelateerd aan de levenscyclus van controllers.
Bijzondere aandacht vereist threadveiligheid. Als viewDidDisappear wordt aangeroepen op de hoofdthread (wat door UIKit wordt gegarandeerd), maar het vrijmaken van bronnen omvat asynchrone operaties, moet de toegang tot gedeelde gegevens worden gesynchroniseerd. Het gebruik van DispatchQueue.main.async binnen viewDidDisappear voor het bijwerken van de UI na voltooiing van een asynchrone taak — een veelgebruikte maar correcte aanpak.
Nog een belangrijk antipatroon — aanroepen van delegatemethoden binnen viewDidDisappear die een nieuwe overgang of modale weergave kunnen initiëren. Dit creëert een cyclus waarin viewDidDisappear opnieuw kan worden aangeroepen voordat de eerste aanroep is voltooid. Apple raadt aan om modale weergaven binnen levenscyclusmethoden te vermijden en deze naar aparte gebeurtenishandlers te verplaatsen.
Veelgestelde vragen
viewWillDisappear wordt aangeroepen voor het begin van de verbergingsanimatie, wanneer de view nog zichtbaar is. viewDidDisappear — na volledige verdwijning van de view. Gebruik viewWillDisappear voor het opslaan van gegevens en viewDidDisappear voor het vrijmaken van bronnen.
Ja, de aanroep van super.viewDidDisappear(animated) is verplicht. UIKit gebruikt deze methode voor interne meldingen en het voltooien van de overgangsstatus. Zonder de super-aanroep zijn crashes in UINavigationController en UITabBarController mogelijk.
Ja, bij interactieve dismiss in iOS 13+ (vegen naar beneden) kan de methode niet worden aangeroepen als de beweging niet is voltooid. Gebruik de delegate UIAdaptivePresentationControllerDelegate en de methode presentationControllerDidDismiss voor gegarandeerde ontvangst van de gebeurtenis.
deinit wordt alleen aangeroepen bij vernietiging van het object, terwijl viewDidDisappear bij elke verberging wordt aangeroepen. Gebruik viewDidDisappear voor het vrijmaken van bronnen bij elke overgang (bijvoorbeeld uitschrijven voor meldingen). Gebruik deinit voor definitieve opschoning bij het verwijderen van de controller.
In SwiftUI wordt in plaats van viewDidDisappear de modifier .onDisappear { } gebruikt. Deze wordt aangeroepen bij het verbergen van de view uit de hiërarchie. In tegenstelling tot UIKit garandeert SwiftUI het aanroepen van onDisappear niet in alle scenario's tijdens animaties.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook