.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 — 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.
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.
struct DetailView: View {
var body: some View {
Text("Detailscherm")
.onDisappear {
print("DetailView verdwenen van scherm")
}
}
}
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.
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.
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.
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.
| Scenario | onDisappear wordt aangeroepen | Opmerking |
|---|---|---|
| Pop in NavigationStack | Ja | Direct na animatie |
| Tab wisselen in TabView | Ja | Huidige tab |
| Dismiss sheet | Ja | Voor voltooiing animatie |
| Scrollen in List | Ja | Cel buiten prefetch-zone |
| App minimaliseren | Nee | Geen garantie van aanroep |
| Crash/watchdog kill | Nee | Wordt niet aangeroepen |
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 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.
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.
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.
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)
])
}
}
}
}
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 |
|---|---|---|
| Aanroepmoment | View toevoegen aan hiërarchie | View verwijderen uit hiërarchie |
| Volgorde | Parent-first | Child-first |
| Garantie | Hoog | Niet bij noodstops |
| Hoofdtaak | Initialisatie | Opschonen |
| Herhaalde aanroep | Bij recreatie van View | Eenmalig per verdwijning |
Aanbeveling: gebruik onDisappear alleen voor niet-kritiek opschonen en tracking. Gebruik voor het opslaan van gegevens scenePhase of applicationWillTerminate-meldingen in AppDelegate.
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 — 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.
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
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.
.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.
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.
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.
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
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