.onDisappear: prinsipyo ng paggana at aplikasyon sa SwiftUI

May-akda: IT Sectr Nai-publish: 2026-06-26 Oras ng pagbabasa: 10 min

.onDisappear — isang SwiftUI modifier na nag-execute ng closure kapag ang View ay inalis mula sa hierarchy ng interface. Ang tawag ay nangyayari kapag nagsasara ng screen, nagpapalit ng tab, nagdi-dismiss ng modal window, o nag-scroll ng elemento palabas ng visible area. Ayon sa Apple Developer Documentation (2026), hindi ginagarantiyahan ng onDisappear ang pagtawag sa mga scenario ng emergency termination o pagkasira ng app ng system-watchdog. Magbasa pa tungkol sa SwiftUI sa materyal tungkol sa SwiftUI.

Mga Pangunahing Punto

  • .onDisappear — SwiftUI modifier para sa pag-execute ng code kapag nawawala ang View.
  • Simetriya — ang onDisappear ay kapares ng onAppear at tinatawag sa reverse order.
  • Paglilinis ng resources — pangunahing scenario: pagkansela ng timer, pagsasara ng koneksyon, pag-save ng estado.
  • Analitika — sa pamamagitan ng onDisappear ipinapadala ang mga event na screen close, dwell time, session end.
  • Walang garantiya — hindi tinatawag ang onDisappear sa emergency termination ng app.

Ano ang .onDisappear?

.onDisappear — isang View modifier sa SwiftUI na tumatanggap ng Void closure at nag-execute nito kapag ang View ay inalis mula sa hierarchy. Kasama ng .onAppear, bumubuo ito ng kumpletong lifecycle ng screen: paglitaw — paggana — pagkawala. Ipinakilala ng Apple ang onDisappear kasabay ng paglabas ng SwiftUI sa iOS 13 bilang analog ng viewDidDisappear mula sa UIKit.

Sa syntax .onDisappear ay identikal sa onAppear: binabago nito ang anumang View at nag-attach ng closure na tinatawag ng SwiftUI component kapag ang view ay inalis. Hindi tulad ng UIKit kung saan ang viewDidDisappear ay nag-a-activate lamang pagkatapos ng transition animation, ang onDisappear sa SwiftUI ay maaaring tawagin bago matapos ang animation — sa sandaling ang View ay minarkahan para sa pag-alis.

Syntax ng onDisappear

Basic syntax ng onDisappear ay kasing-concise ng onAppear. Ang modifier ay hindi tumatanggap ng karagdagang mga parameter — tanging ang closure na nag-e-execute nang synchronously sa main thread.

swift
struct DetailView: View {
    var body: some View {
        Text("Screen ng Detalye")
            .onDisappear {
                print("DetailView ay nawala mula sa screen")
            }
    }
}

Paano gumagana ang .onDisappear

Mekanismo ng pagtawag ng onDisappear ay kabaligtaran ng onAppear: unang tumatanggap ang mga child element ng onDisappear, pagkatapos ang parent. Ang child-first rule na ito ay ginagarantiyahan na ang resources ng child elements ay nailalabas bago ang resources ng parent. Kung ang child element ay nakadepende sa data ng parent, dapat itong makapag-terminate nang tama nang walang konteksto ng parent.

SwiftUI ay tumatawag ng onDisappear sa sandaling ang View ay na-exclude mula sa render graph. Ang trigger ay maaaring: pop mula sa NavigationStack, pagpapalit ng TabView, dismiss ng modal window (sheet/fullScreenCover), pagbabago ng conditionally displayed View (if/switch). Sa List at ScrollView, ang onDisappear ay tinatawag kapag ang cell ay na-scroll palabas ng prefetch buffer.

Order ng pagtawag ng child-first

Child-first order ay nangangahulugan na kung may tatlong child View sa VStack, ang onDisappear ay tatawagin muna para sa bawat child sa reverse order, pagkatapos para sa parent. Ito ay kritikal para sa tamang paglilinis: ang child timer ay kinakansela bago ilabas ng parent ViewModel ang shared resources.

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

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

Output sa console: Child B onDisappear, Child A onDisappear, Parent onDisappear — panghuli. Ang reverse order kumpara sa onAppear ay ginagarantiyahan ang tamang release chain.

Kailan tinatawag ang .onDisappear

Mga scenario ng pagtawag ng onDisappear ay depende sa uri ng container. Sa NavigationStack ang onDisappear ay nagti-trigger sa pop-to-root, ordinaryong pop-back, o pag-alis ng screen sa pamamagitan ng swipe gesture (interactivePopGestureRecognizer). Sa TabView ang pagpapalit ng tab ay nagti-trigger ng onDisappear para sa nakatago at onAppear para sa ipinapakita — parehong modifier ay nagti-trigger nang halos sabay.

Sa Sheet at fullScreenCover ang onDisappear ay tinatawag sa programmatic dismiss (sa pamamagitan ng @Environment(\.dismiss)) o pababang swipe gesture. Mahalagang feature: kung ang sheet ay binuksan ngunit ang user ay lumipat ng app, ang onDisappear ay HINDI tinatawag hanggang sa aktwal na pagsasara.

ScenarioonDisappear ay tinatawagTala
Pop sa NavigationStackOoKaagad pagkatapos ng animation
Pagpapalit ng tab sa TabViewOoKasalukuyang tab
Dismiss ng sheetOoBago matapos ang animation
Scroll sa ListOoCell lumabas sa prefetch zone
Pag-minimize ng appHindiWalang garantiya ng pagtawag
Crash/watchdog killHindiHindi tinatawag

Mga halimbawa ng .onDisappear

Pangunahing scenario ng onDisappear — paglilinis ng resources, pag-save ng estado, at pag-track. Hindi tulad ng onAppear, ang mga gawain ng onDisappear ay na-e-execute sa paglabas at hindi nangangailangan ng pagsusuri para sa pagdodoble, dahil ang View ay nawawala nang isang beses.

Pag-save ng estado at pagkansela ng timer

Pag-save ng estado sa onDisappear ay lalong kapaki-pakinabang para sa mga form kung saan ang data ay dapat i-save kapag umaalis sa screen. Ang mga timer at Combine subscription ay kinakansela sa onDisappear upang maiwasan ang memory leaks kapag bumalik sa screen.

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

Pagkansela ng timer sa onDisappear ay pumipigil sa pag-execute ng code pagkatapos na sarado ang screen. Kung walang pagkansela, maaaring subukan ng timer na i-update ang @State na hindi na kabilang sa kasalukuyang View, na nagdudulot ng runtime warning.

Pag-track ng oras sa screen

Tagal ng pananatili sa screen — isang klasikong tracking scenario. Itinatala namin ang oras sa onAppear, kinakalkula ang pagkakaiba sa onDisappear, at nagpapadala ng analytic event na may tagal ng session.

swift
struct TrackedView: View {
    @State private var appearTime: Date?
    
    var body: some View {
        Text("Subaybayan na Screen")
            .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 — mga pagkakaiba

Pangunahing pagkakaiba ng onDisappear sa onAppear — order ng pagtawag at mga garantiya ng pag-activate. Ang onAppear ay tinatawag kapag ang View ay idinagdag sa hierarchy at may property na muling tawagin sa recreation. Ang onDisappear ay tinatawag sa pag-alis at garantisadong gumagana lamang sa normal na pagsasara, ngunit hindi sa mga emergency scenario.

Ayon sa WWDC 2024, inirerekomenda ng Apple na ituring ang onDisappear bilang cleanup point, hindi bilang data save point. Ang kritikal na mahalagang data (mga pagbabayad, rehistrasyon) ay dapat i-save sa real-time, hindi sa sandaling mawala ang View, dahil hindi ginagarantiyahan ng onDisappear ang pagtawag kapag ang app ay na-minimize.

Katangian.onAppear.onDisappear
Sandali ng pagtawagPagdagdag ng View sa hierarchyPag-alis ng View mula sa hierarchy
OrderParent-firstChild-first
GarantiyaMataasWala sa emergency termination
Pangunahing gawainInisyalisasyonPaglilinis
Muling pagtawagSa recreation ng ViewIsang beses bawat pagkawala

Rekomendasyon: gamitin lamang ang onDisappear para sa hindi kritikal na paglilinis at pag-track. Para sa pag-save ng data, gamitin ang scenePhase o mga notification ng applicationWillTerminate sa AppDelegate.

Mga karaniwang scenario ng paggamit

Scenario 1: pag-load na parang YouTube. Sa screen ng detalye ng video, sine-save ng onDisappear ang posisyon ng playback sa UserDefaults. Sa muling pagbukas, ini-restore ng onAppear ang posisyon mula sa UserDefaults, na nagbibigay ng epekto ng tuloy-tuloy na panonood.

Scenario 2: pagkansela ng Combine subscription. Kung ang ViewModel ay gumagamit ng Combine publishers, kinakansela ng onDisappear ang subscription sa pamamagitan ng cancellable?.cancel(). Pinipigilan nito ang pag-update ng UI pagkatapos umalis sa screen, na lalong mahalaga para sa mga listahang may pagination at mga query sa paghahanap.

Scenario 3: pagsasara ng WebSocket. Sa mga app na may real-time na koneksyon (mga messenger, feed ng presyo) isinasara ng onDisappear ang WebSocket connection para makatipid sa baterya at trapiko. Ang muling pagbubukas ay ginagawa sa onAppear kapag bumalik sa screen.

Pagsasara ng WebSocket sa onDisappear

WebSocket — isang tipikal na resource na kailangang isara kapag umaalis sa screen. Sa halimbawa sa ibaba, dinidiskonekta ng onDisappear ang socket, at muling ikinokonekta ito ng onAppear, na nagbibigay ng malaking pagtitipid sa trapiko para sa mga app na may maraming screen.

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

Mahalaga: kapag lumilipat sa pagitan ng mga tab sa TabView, ang onDisappear ng kasalukuyang tab at onAppear ng susunod na tab ay nagti-trigger nang halos sabay. Para sa WebSocket ito ay maaaring humantong sa isang disconnect-connect cycle na lumilikha ng karagdagang load. Solusyon — gumamit ng delay o suriin kung kailangan ang socket sa susunod na screen.

Mga Madalas Itanong

Maaari bang hindi tawagin ang .onDisappear?

Oo, hindi ginagarantiyahan ng .onDisappear ang pagtawag sa emergency termination ng app (crash, watchdog kill), pag-minimize ng app nang hindi isinasara ang screen, o system scenario kung saan ang app ay nawasak sa background. Para sa kritikal na mahalagang data, gamitin ang scenePhase o applicationWillTerminate.

Paano iiba ang .onDisappear mula sa .scenePhase?

.onDisappear ay nagti-trigger kapag ang View ay inalis mula sa hierarchy — isang lokal na callback para sa isang partikular na screen. .scenePhase (sa pamamagitan ng @Environment(\.scenePhase)) ay nagti-trigger kapag nagbago ang estado ng buong app: active, inactive, background. Para sa pag-track ng oras sa screen, gamitin ang onAppear+onDisappear, para sa pag-save ng global state — scenePhase.

Bakit maraming beses na tinatawag ang .onDisappear nang sunud-sunod?

Ang dahilan — mabilis na paglipat sa pagitan ng mga tab o paulit-ulit na push/pop ng parehong screen. Ang SwiftUI ay maaaring gumawa ng bagong instance ng View, alisin ang luma, gumawa muli — bawat beses na nagti-trigger ng onDisappear at onAppear. Suriin kung gumagamit ka ng .id(), .equatable() o kung ni-re-recreate mo ang View sa body ng parent.

Gumagana ba ang .onDisappear sa SwiftUI sa macOS?

Oo, ang .onDisappear ay ganap na suportado sa macOS (10.15+) na may parehong pag-uugali: tinatawag kapag nagsasara ng window, nag-aalis ng split view panel, o nagdi-dismiss ng modal window. Sa macOS ang onDisappear ay tinatawag din kapag nagtatago ng window (hide), hindi lamang kapag nagsasara, na mahalaga para sa macOS apps.

Paano kanselahin ang URLSessionTask sa .onDisappear?

I-save ang referensya sa URLSessionTask sa @State at tawagin ang task.cancel() sa onDisappear. Bilang alternatibo, gamitin ang .task modifier na awtomatikong kinakansela ang async operation kapag nawala ang View. Ang .task ay mas pinipili para sa lahat ng async operations, kabilang ang URLSession.

Buod

  • .onDisappear — kapares na modifier ng onAppear para sa paglilinis ng resources at pag-track kapag nawawala ang View.
  • Child-first order — ang child View ay tumatanggap ng onDisappear nang mas maaga kaysa sa parent para sa tamang release chain.
  • Walang garantiya ng pagtawag — sa crash, pag-minimize, o system termination, maaaring hindi gumana ang onDisappear.
  • Pangunahing scenario — pagkansela ng timer, pagsasara ng WebSocket, pag-save ng estado, pag-track ng tagal.
  • Analitika — ang onDisappear ay nagpapadala ng screen_close events na may pagkalkula ng dwell time sa pamamagitan ng Date().timeIntervalSince.
  • Para sa async operations — gamitin ang .task sa halip na onDisappear kasama ng Task {}, dahil awtomatikong kinakansela ng .task ang mga request.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din