.onDisappear: werkingsprincipe en toepassing in SwiftUI

Auteur: IT Sectr Gepubliceerd: 2026-06-26 Leestijd: 10 min

.onDisappear — een SwiftUI-modificator die een afsluiting uitvoert wanneer een View uit de interfacehiërarchie wordt verwijderd. De aanroep vindt plaats bij het sluiten van een scherm, het wisselen van een tab, het dismissen van een modaal venster of het scrollen van een element buiten het zichtbare gebied. Volgens Apple Developer Documentation (2026) garandeert onDisappear geen aanroep in scenario's van noodstop of bij vernietiging van de app door system-watchdog. Lees meer over SwiftUI in het materiaal over SwiftUI.

Belangrijkste

  • .onDisappear — SwiftUI-modificator voor het uitvoeren van code bij het verdwijnen van een View.
  • Symmetrie — onDisappear is de tegenhanger van onAppear en wordt in omgekeerde volgorde aangeroepen.
  • Resources opschonen — het belangrijkste scenario: timers annuleren, verbindingen sluiten, toestand opslaan.
  • Analytics — via onDisappear worden gebeurtenissen screen close, dwell time, session end verzonden.
  • Geen garantie — onDisappear wordt niet aangeroepen bij noodstop van de app.

Wat is .onDisappear?

.onDisappear — een View-modificator in SwiftUI die een Void-afsluiting accepteert en uitvoert wanneer een View uit de hiërarchie wordt verwijderd. Samen met .onAppear vormt het de volledige levenscyclus van een scherm: verschijnen — werken — verdwijnen. Apple introduceerde onDisappear samen met de release van SwiftUI in iOS 13 als een analogon van viewDidDisappear uit UIKit.

Syntax-wise is .onDisappear identiek aan onAppear: het wijzigt elke View en koppelt een afsluiting die door de SwiftUI-component wordt aangeroepen bij het verwijderen van de weergave. In tegenstelling tot UIKit, waar viewDidDisappear pas wordt geactiveerd na voltooiing van de overgangsanimatie, kan onDisappear in SwiftUI worden aangeroepen voordat de animatie is voltooid — op het moment dat de View wordt gemarkeerd voor verwijdering.

Syntax van onDisappear

Basis syntax van onDisappear is even beknopt als die van onAppear. De modificator accepteert geen extra parameters — alleen de afsluiting die synchroon in de hoofdthread wordt uitgevoerd.

swift
struct DetailView: View {
    var body: some View {
        Text("Detailscherm")
            .onDisappear {
                print("DetailView verdwenen van scherm")
            }
    }
}

Hoe werkt .onDisappear

Aanroepmechanisme van onDisappear is het tegenovergestelde van onAppear: eerst ontvangen onderliggende elementen onDisappear, dan de ouder. Deze child-first-regel garandeert dat resources van onderliggende elementen worden vrijgegeven voordat de resources van de ouder worden vrijgegeven. Als een onderliggend element afhankelijk is van gegevens van de ouder, moet het correct kunnen worden afgesloten zonder de oudercontext.

SwiftUI roept onDisappear aan op het moment dat de View uit de render-graaf wordt verwijderd. Triggers kunnen zijn: pop uit NavigationStack, wisselen van TabView, dismiss van een modaal venster (sheet/fullScreenCover), wijzigen van een voorwaardelijk weergegeven View (if/switch). In List en ScrollView wordt onDisappear aangeroepen bij het scrollen van een cel buiten de prefetch-buffer.

Aanroepvolgorde child-first

Child-first-volgorde betekent dat als er drie onderliggende Views in een VStack zitten, onDisappear eerst voor elk kind in omgekeerde volgorde wordt aangeroepen, daarna voor de ouder. Dit is cruciaal voor correct opschonen: onderliggende timers worden geannuleerd voordat de ouderlijke ViewModel gedeelde resources vrijgeeft.

swift
struct ParentView: View {
    var body: some View {
        VStack {
            ChildView(id: "A")
            ChildView(id: "B")
        }
        .onDisappear {
            print("Parent onDisappear — laatste")
        }
    }
}

struct ChildView: View {
    let id: String
    var body: some View {
        Text("Kind \(id)")
            .onDisappear {
                print("Kind \(id) onDisappear")
            }
    }
}

Console-uitvoer: Child B onDisappear, Child A onDisappear, Parent onDisappear — als laatste. De omgekeerde volgorde in vergelijking met onAppear garandeert een correcte vrijgaveketen.

Wanneer wordt .onDisappear aangeroepen

Aanroepscenario's van onDisappear zijn afhankelijk van het containertype. In NavigationStack wordt onDisappear geactiveerd bij pop-to-root, gewone pop-back of verwijdering van een scherm via een veeggebaar (interactivePopGestureRecognizer). In TabView zorgt het wisselen van een tab voor onDisappear voor de verborgen tab en onAppear voor de weergegeven tab — beide modificatoren worden bijna gelijktijdig geactiveerd.

In Sheet en fullScreenCover wordt onDisappear aangeroepen bij programmatische dismiss (via @Environment(\.dismiss)) of een neerwaarts veeggebaar. Een belangrijke eigenschap: als een sheet is geopend maar de gebruiker de app heeft gewisseld, wordt onDisappear NIET aangeroepen tot de daadwerkelijke sluiting.

ScenarioonDisappear wordt aangeroepenOpmerking
Pop in NavigationStackJaDirect na animatie
Tab wisselen in TabViewJaHuidige tab
Dismiss sheetJaVoor voltooiing animatie
Scrollen in ListJaCel buiten prefetch-zone
App minimaliserenNeeGeen garantie van aanroep
Crash/watchdog killNeeWordt niet aangeroepen

Voorbeelden van .onDisappear

Belangrijkste scenario's van onDisappear — resources opschonen, toestand opslaan en tracking. In tegenstelling tot onAppear worden onDisappear-taken bij het verlaten uitgevoerd en vereisen ze geen controle op duplicatie, omdat de View eenmalig verdwijnt.

Toestand opslaan en timers annuleren

Toestand opslaan in onDisappear is vooral nuttig voor formulieren waar gegevens moeten worden opgeslagen bij het verlaten van het scherm. Timers en Combine-abonnementen worden in onDisappear geannuleerd om geheugenlekken bij terugkeer naar het scherm te voorkomen.

swift
struct FormView: View {
    @State private var draftText = ""
    @State private var timer: Timer?
    
    var body: some View {
        TextField("Enter text", text: $draftText)
            .onAppear {
                timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { _ in
                    saveDraft()
                }
            }
            .onDisappear {
                timer?.invalidate()
                timer = nil
                saveDraft()
            }
    }
    
    private func saveDraft() {
        UserDefaults.standard.set(draftText, forKey: "draft")
    }
}

Timer annuleren in onDisappear voorkomt dat code wordt uitgevoerd nadat het scherm al is gesloten. Zonder annulering kan de timer proberen een @State bij te werken die niet langer bij de huidige View hoort, wat een runtime-waarschuwing veroorzaakt.

Tijd op scherm bijhouden

Verblijfsduur op het scherm — een klassiek trackingscenario. We registreren de tijd in onAppear, berekenen het verschil in onDisappear en sturen een analytische gebeurtenis met de sessieduur.

swift
struct TrackedView: View {
    @State private var appearTime: Date?
    
    var body: some View {
        Text("Gevolgd Scherm")
            .onAppear {
                appearTime = Date()
                Analytics.shared.logEvent("screen_view", params: ["screen": "TrackedView"])
            }
            .onDisappear {
                if let start = appearTime {
                    let duration = Date().timeIntervalSince(start)
                    Analytics.shared.logEvent("screen_close", params: [
                        "screen": "TrackedView",
                        "duration_ms": Int(duration * 1000)
                    ])
                }
            }
    }
}

.onDisappear vs .onAppear — verschillen

Het belangrijkste verschil tussen onDisappear en onAppear — de aanroepvolgorde en activeringsgaranties. onAppear wordt aangeroepen bij het toevoegen van een View aan de hiërarchie en heeft de eigenschap opnieuw te worden aangeroepen bij recreatie. onDisappear wordt aangeroepen bij verwijdering en werkt gegarandeerd alleen bij normaal sluiten, maar niet in noodsituaties.

Volgens WWDC 2024 raadt Apple aan om onDisappear te beschouwen als een opschoonpunt, niet als een gegevensopslagpunt. Kritiek belangrijke gegevens (betalingen, registraties) moeten in realtime worden opgeslagen, niet op het moment dat de View verdwijnt, omdat onDisappear geen aanroep garandeert bij het minimaliseren van de app.

Kenmerk.onAppear.onDisappear
AanroepmomentView toevoegen aan hiërarchieView verwijderen uit hiërarchie
VolgordeParent-firstChild-first
GarantieHoogNiet bij noodstops
HoofdtaakInitialisatieOpschonen
Herhaalde aanroepBij recreatie van ViewEenmalig per verdwijning

Aanbeveling: gebruik onDisappear alleen voor niet-kritiek opschonen en tracking. Gebruik voor het opslaan van gegevens scenePhase of applicationWillTerminate-meldingen in AppDelegate.

Typische toepassingsscenario's

Scenario 1: YouTube-achtig laden. Op het videoscherm slaat onDisappear de afspeelpositie op in UserDefaults. Bij heropenen herstelt onAppear de positie uit UserDefaults, wat een continu kijkeffect geeft.

Scenario 2: Combine-abonnement annuleren. Als ViewModel Combine-publishers gebruikt, annuleert onDisappear het abonnement via cancellable?.cancel(). Dit voorkomt UI-updates na het verlaten van het scherm, wat vooral belangrijk is voor lijsten met paginering en zoekopdrachten.

Scenario 3: WebSocket sluiten. In apps met real-time verbindingen (messengers, koersfeeds) sluit onDisappear de WebSocket-verbinding om batterij en data te besparen. Heropening vindt plaats in onAppear bij terugkeer naar het scherm.

WebSocket sluiten in onDisappear

WebSocket — een typische resource die moet worden gesloten bij het verlaten van het scherm. In het onderstaande voorbeeld verbreekt onDisappear de socket en maakt onAppear deze opnieuw verbinding, wat aanzienlijke databesparing oplevert voor apps met meerdere schermen.

swift
struct ChatView: View {
    @StateObject private var socket = WebSocketManager()
    
    var body: some View {
        ChatListView(messages: socket.messages)
            .onAppear {
                socket.connect()
            }
            .onDisappear {
                socket.disconnect()
            }
    }
}

Belangrijk: bij het wisselen tussen tabs in TabView worden onDisappear van de huidige tab en onAppear van de volgende tab bijna gelijktijdig geactiveerd. Voor WebSocket kan dit leiden tot een disconnect-connect-cyclus die extra belasting veroorzaakt. Oplossing — gebruik een vertraging of controleer of de socket nodig is op het volgende scherm.

Veelgestelde vragen

Kan .onDisappear worden overgeslagen?

Ja, .onDisappear garandeert geen aanroep bij noodstop van de app (crash, watchdog kill), minimaliseren van de app zonder het scherm te sluiten of een systeemscenario waarbij de app op de achtergrond wordt vernietigd. Gebruik voor kritiek belangrijke gegevens scenePhase of applicationWillTerminate.

Hoe onderscheid je .onDisappear van .scenePhase?

.onDisappear wordt geactiveerd bij verwijdering van een View uit de hiërarchie — een lokale callback voor een specifiek scherm. .scenePhase (via @Environment(\.scenePhase)) wordt geactiveerd bij wijziging van de status van de hele app: active, inactive, background. Gebruik onAppear+onDisappear voor het bijhouden van schermtijd en scenePhase voor het opslaan van de globale toestand.

Waarom wordt .onDisappear meerdere keren achter elkaar aangeroepen?

De oorzaak — snel wisselen tussen tabs of herhaaldelijk push/pop van hetzelfde scherm. SwiftUI kan een nieuwe View-instantie maken, de oude verwijderen, opnieuw maken — elke keer onDisappear en onAppear aanroepend. Controleer of u .id(), .equatable() gebruikt of de View in de body van de ouder herbouwt.

Werkt .onDisappear in SwiftUI op macOS?

Ja, .onDisappear wordt volledig ondersteund op macOS (10.15+) met hetzelfde gedrag: aangeroepen bij het sluiten van een venster, verwijderen van een split view-paneel of dismiss van een modaal venster. Op macOS wordt onDisappear ook aangeroepen bij het verbergen van een venster (hide), niet alleen bij sluiten, wat belangrijk is voor macOS-apps.

Hoe annuleer ik URLSessionTask in .onDisappear?

Sla de referentie naar URLSessionTask op in @State en roep task.cancel() aan in onDisappear. Gebruik alternatief de .task-modificator die de async-operatie automatisch annuleert wanneer de View verdwijnt. .task heeft de voorkeur voor alle async-operaties, inclusief URLSession.

Samenvatting

  • .onDisappear — tegenhanger van onAppear voor het opschonen van resources en tracking bij het verdwijnen van een View.
  • Child-first-volgorde — onderliggende Views ontvangen onDisappear eerder dan de ouder voor een correcte vrijgaveketen.
  • Geen aanroepgarantie — bij crash, minimaliseren of systeembeëindiging werkt onDisappear mogelijk niet.
  • Belangrijkste scenario's — timers annuleren, WebSocket sluiten, toestand opslaan, duur bijhouden.
  • Analytics — onDisappear verzendt screen_close-gebeurtenissen met berekening van dwell time via Date().timeIntervalSince.
  • Voor async-operaties — gebruik .task in plaats van onDisappear met Task {}, omdat .task verzoeken automatisch annuleert.

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.

Bespreek het project

Lees ook