.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 — 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.
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.
struct DetailView: View {
var body: some View {
Text("Screen ng Detalye")
.onDisappear {
print("DetailView ay nawala mula sa screen")
}
}
}
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.
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.
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.
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.
| Scenario | onDisappear ay tinatawag | Tala |
|---|---|---|
| Pop sa NavigationStack | Oo | Kaagad pagkatapos ng animation |
| Pagpapalit ng tab sa TabView | Oo | Kasalukuyang tab |
| Dismiss ng sheet | Oo | Bago matapos ang animation |
| Scroll sa List | Oo | Cell lumabas sa prefetch zone |
| Pag-minimize ng app | Hindi | Walang garantiya ng pagtawag |
| Crash/watchdog kill | Hindi | Hindi tinatawag |
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 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.
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.
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.
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)
])
}
}
}
}
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 pagtawag | Pagdagdag ng View sa hierarchy | Pag-alis ng View mula sa hierarchy |
| Order | Parent-first | Child-first |
| Garantiya | Mataas | Wala sa emergency termination |
| Pangunahing gawain | Inisyalisasyon | Paglilinis |
| Muling pagtawag | Sa recreation ng View | Isang 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.
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.
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.
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
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.
.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.
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.
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.
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
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.
Basahin din