.onDisappear: működési elv és alkalmazás SwiftUI-ban

Szerző: IT Sectr Megjelenés: 2026-06-26 Olvasási idő: 10 perc

.onDisappear — egy SwiftUI-módosító, amely egy lezárást hajt végre, amikor egy View eltávolításra kerül az interfész hierarchiájából. A hívás a képernyő bezárásakor, lap váltásakor, modális ablak elutasításakor vagy egy elem látható területen kívülre görgetésekor történik. Az Apple Developer Documentation (2026) szerint az onDisappear nem garantálja a hívást vészhelyzeti megszakítás vagy az alkalmazás system-watchdog általi megsemmisítése esetén. További információ a SwiftUI-ról a SwiftUI anyagában olvasható.

Főbb pontok

  • .onDisappear — SwiftUI-módosító kód végrehajtásához, amikor egy View eltűnik.
  • Szimmetria — az onDisappear párja az onAppearnek és fordított sorrendben hívódik.
  • Erőforrások tisztítása — fő forgatókönyv: időzítők törlése, kapcsolatok bezárása, állapot mentése.
  • Analitika — az onDisappearen keresztül screen close, dwell time, session end eseményeket küldenek.
  • Garancia hiánya — az onDisappear nem hívódik meg az alkalmazás vészhelyzeti megszakításakor.

Mi az .onDisappear?

.onDisappear — egy View-módosító a SwiftUI-ban, amely egy Void lezárást fogad el és végrehajtja, amikor a View eltávolításra kerül a hierarchiából. Az .onAppear-rel párban alkotja a képernyő teljes életciklusát: megjelenés — működés — eltűnés. Az Apple az onDisappeart a SwiftUI iOS 13-as megjelenésével együtt vezette be az UIKit viewDidDisappear analógjaként.

Szintaktikailag .onDisappear megegyezik az onAppearrel: bármely View-t módosít, és egy lezárást csatol, amelyet a SwiftUI komponens hív meg a nézet eltávolításakor. Az UIKit-től eltérően, ahol a viewDidDisappear csak az átmeneti animáció befejezése után aktiválódik, az onDisappear SwiftUI-ban az animáció befejezése előtt is meghívható — abban a pillanatban, amikor a View eltávolításra van jelölve.

Az onDisappear szintaxisa

Alap szintaxis az onDisappear ugyanolyan tömör, mint az onAppear. A módosító nem fogad el további paramétereket — csak a lezárást, amely szinkron módon a fő szálon hajtódik végre.

swift
struct DetailView: View {
    var body: some View {
        Text("Részlet Képernyő")
            .onDisappear {
                print("DetailView eltűnt a képernyőről")
            }
    }
}

Hogyan működik az .onDisappear

A hívás mechanizmusa az onDisappear ellentéte az onAppearnek: először a gyermek elemek kapják meg az onDisappeart, majd a szülő. Ez a child-first szabály garantálja, hogy a gyermek elemek erőforrásai a szülő erőforrásainak felszabadítása előtt szabadulnak fel. Ha egy gyermek elem függ a szülő adataitól, képesnek kell lennie a szülő kontextus nélküli helyes befejeződésre.

SwiftUI az onDisappeart abban a pillanatban hívja meg, amikor a View kikerül a renderelési gráfból. Kiváltó ok lehet: pop a NavigationStackből, TabView váltása, modális ablak elutasítása (sheet/fullScreenCover), feltételesen megjelenített View változása (if/switch). Listában és ScrollViewban az onDisappear akkor hívódik, amikor egy cella a prefetch pufferén kívülre görget.

Child-first hívási sorrend

Child-first sorrend azt jelenti, hogy ha három gyermek View van egy VStackben, az onDisappear először minden gyermekre fordított sorrendben hívódik, majd a szülőre. Ez kritikus a helyes tisztításhoz: a gyermek időzítők törlésre kerülnek, mielőtt a szülő ViewModel felszabadítaná a megosztott erőforrásokat.

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

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

Konzol kimenet: Child B onDisappear, Child A onDisappear, Parent onDisappear — utolsóként. Az onAppearhez képest fordított sorrend garantálja a helyes felszabadítási láncot.

Mikor hívódik meg az .onDisappear

A hívás forgatókönyvei az onDisappear a tároló típusától függenek. NavigationStackben az onDisappear pop-to-root, szokásos pop-back vagy a képernyő húzással történő eltávolításakor (interactivePopGestureRecognizer) aktiválódik. TabViewben a lapváltás onDisappeart vált ki az elrejtett lapra és onAppeart a megjelenítettre — mindkét módosító szinte egyidejűleg aktiválódik.

Sheetben és fullScreenCoverben az onDisappear programozott elutasításkor (az @Environment(\.dismiss) segítségével) vagy lefelé húzó gesztussal hívódik meg. Fontos jellemző: ha a sheet meg volt nyitva, de a felhasználó alkalmazást váltott, az onDisappear NEM hívódik meg a tényleges bezárásig.

ForgatókönyvonDisappear meghívódikMegjegyzés
Pop a NavigationStackbenIgenAz animáció után azonnal
TabView lap váltásIgenAktuális lap
Sheet elutasításaIgenAz animáció befejezése előtt
Görgetés ListábanIgenCella elhagyta a prefetch zónát
Alkalmazás minimalizálásaNemNincs garancia a hívásra
Crash/watchdog killNemNem hívódik meg

.onDisappear példák

Fő forgatókönyvek az onDisappear — erőforrások tisztítása, állapot mentése és nyomon követés. Az onAppeartől eltérően az onDisappear feladatok kilépéskor hajtódnak végre, és nem igényelnek ismétlődés ellenőrzést, mivel a View egyszer tűnik el.

Állapot mentése és időzítők törlése

Állapot mentése az onDisappearben különösen hasznos olyan űrlapok esetén, ahol az adatokat a képernyő elhagyásakor kell menteni. Az időzítők és Combine feliratkozások az onDisappearben törlődnek, hogy elkerüljék a memóriaszivárgást a képernyőre való visszatéréskor.

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")
    }
}

Időzítő törlése az onDisappearben megakadályozza a kód végrehajtását a képernyő bezárása után. Törlés nélkül az időzítő megpróbálhat frissíteni egy @State-et, amely már nem tartozik az aktuális View-hoz, futásidejű figyelmeztetést okozva.

Képernyőn töltött idő nyomon követése

Tartózkodási idő a képernyőn — klasszikus nyomon követési forgatókönyv. Rögzítjük az időt az onAppearben, kiszámítjuk a különbséget az onDisappearben, és analitikai eseményt küldünk a munkamenet időtartamával.

swift
struct TrackedView: View {
    @State private var appearTime: Date?
    
    var body: some View {
        Text("Követett Képernyő")
            .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 — különbségek

Fő különbség az onDisappear és az onAppear között — a hívás sorrendje és az aktiválási garanciák. Az onAppear akkor hívódik, amikor a View hozzáadásra kerül a hierarchiához, és újrahívási tulajdonsággal rendelkezik újbóli létrehozáskor. Az onDisappear eltávolításkor hívódik, és csak normál bezáráskor garantáltan működik, de vészhelyzeti forgatókönyvek esetén nem.

A WWDC 2024 szerint az Apple azt ajánlja, hogy az onDisappeart tisztítási pontként kezeljék, nem adatmentési pontként. A kritikus fontosságú adatokat (fizetések, regisztrációk) valós időben kell menteni, nem a View eltűnésének pillanatában, mivel az onDisappear nem garantálja a hívást az alkalmazás minimalizálásakor.

Jellemző.onAppear.onDisappear
Hívás pillanataView hozzáadása hierarchiáhozView eltávolítása hierarchiából
SorrendParent-firstChild-first
GaranciaMagasNincs vészhelyzeti megszakításnál
Fő feladatInicializálásTisztítás
ÚjrahívásA View újbóli létrehozásakorEgyszeri eltűnésenként

Javaslat: az onDisappeart csak nem kritikus tisztításhoz és nyomon követéshez használja. Adatok mentéséhez használja a scenePhase-t vagy az applicationWillTerminate értesítéseket az AppDelegate-ben.

Tipikus alkalmazási forgatókönyvek

1. forgatókönyv: YouTube-szerű betöltés. A videó részletei képernyőn az onDisappear elmenti a lejátszási pozíciót a UserDefaultsba. Újbóli megnyitáskor az onAppear visszaállítja a pozíciót a UserDefaultsból, folyamatos nézési hatást keltve.

2. forgatókönyv: Combine feliratkozás törlése. Ha a ViewModel Combine kiadókat használ, az onDisappear törli a feliratkozást a cancellable?.cancel() segítségével. Ez megakadályozza a UI frissítését a képernyő elhagyása után, ami különösen fontos lapozható listák és keresési lekérdezések esetén.

3. forgatókönyv: WebSocket bezárása. Valós idejű kapcsolatokkal rendelkező alkalmazásokban (üzenetküldők, árfolyam hírcsatornák) az onDisappear bezárja a WebSocket kapcsolatot az akkumulátor és a forgalom megtakarítása érdekében. Az újbóli megnyitás az onAppearben történik a képernyőre való visszatéréskor.

WebSocket bezárása onDisappearben

WebSocket — tipikus erőforrás, amelyet be kell zárni a képernyő elhagyásakor. Az alábbi példában az onDisappear bontja a socketet, az onAppear pedig újracsatlakoztatja, ami jelentős forgalom megtakarítást eredményez a több képernyős alkalmazások számára.

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

Fontos: a TabView lapjai közötti váltáskor az aktuális lap onDisappear és a következő lap onAppear szinte egyszerre aktiválódik. WebSocket esetén ez disconnect-connect ciklushoz vezethet, amely többletterhelést okoz. Megoldás — késleltetés használata vagy annak ellenőrzése, hogy szükség van-e a socketre a következő képernyőn.

Gyakran Ismételt Kérdések

Előfordulhat, hogy az .onDisappear nem hívódik meg?

Igen, az .onDisappear nem garantálja a hívást az alkalmazás vészhelyzeti megszakításakor (crash, watchdog kill), az alkalmazás képernyő bezárása nélküli minimalizálásakor, vagy olyan rendszerforgatókönyv esetén, amikor az alkalmazás a háttérben megsemmisül. Kritikus fontosságú adatokhoz használja a scenePhase-t vagy az applicationWillTerminate-t.

Hogyan különböztethető meg az .onDisappear a .scenePhase-től?

.onDisappear akkor aktiválódik, amikor egy View eltávolításra kerül a hierarchiából — egy helyi visszahívás egy adott képernyőhöz. .scenePhase (az @Environment(\.scenePhase) segítségével) akkor aktiválódik, amikor a teljes alkalmazás állapota megváltozik: active, inactive, background. A képernyőn töltött idő nyomon követéséhez használja az onAppear+onDisappeart, a globális állapot mentéséhez a scenePhase-t.

Miért hívódik meg az .onDisappear többször egymás után?

Az ok — gyors lapozás a lapok között vagy ugyanazon képernyő ismételt push/pop-ja. A SwiftUI létrehozhat egy új View-példányt, eltávolíthatja a régit, majd újra létrehozhatja — minden alkalommal onDisappeart és onAppeart kiváltva. Ellenőrizze, hogy használ-e .id()-t, .equatable()-t, vagy hogy újra létrehozza-e a View-t a szülő body-jában.

Működik az .onDisappear a SwiftUI-ban macOS-en?

Igen, az .onDisappear teljes mértékben támogatott macOS-en (10.15+) ugyanazzal a viselkedéssel: ablak bezárásakor, split view panel eltávolításakor vagy modális ablak elutasításakor hívódik. macOS-en az onDisappear az ablak elrejtésekor (hide) is meghívódik, nem csak bezáráskor, ami fontos a macOS alkalmazások esetében.

Hogyan törölhető URLSessionTask az .onDisappearben?

Mentse el a URLSessionTask-re való hivatkozást @State-be, és hívja meg a task.cancel()-t az onDisappearben. Alternatívaként használja a .task módosítót, amely automatikusan törli az async műveletet a View eltűnésekor. A .task előnyben részesítendő minden async művelethez, beleértve a URLSession-t is.

Összefoglalás

  • .onDisappear — az onAppear pár módosítója erőforrások tisztításához és nyomon követéshez a View eltűnésekor.
  • Child-first sorrend — a gyermek View-k korábban kapják meg az onDisappeart, mint a szülő a helyes felszabadítási lánchoz.
  • Nincs garancia a hívásra — crash, minimalizálás vagy rendszer-megszakítás esetén az onDisappear nem működhet.
  • Fő forgatókönyvek — időzítők törlése, WebSocket bezárása, állapot mentése, időtartam nyomon követése.
  • Analitika — az onDisappear screen_close eseményeket küld a dwell time kiszámításával a Date().timeIntervalSince segítségével.
  • Async műveletekhez — használja a .task-ot az onDisappear helyett a Task {}-val, mivel a .task automatikusan törli a kéréseket.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is