.onDisappear: prinsip kerja dan penerapan di SwiftUI

Penulis: IT Sectr Diterbitkan: 2026-06-26 Waktu membaca: 10 mnt

.onDisappear — modifier SwiftUI yang mengeksekusi closure ketika View dihapus dari hierarki antarmuka. Panggilan terjadi saat menutup layar, mengganti tab, dismiss jendela modal, atau scroll elemen keluar dari area pandang. Menurut Apple Developer Documentation (2026), onDisappear tidak menjamin panggilan dalam skenario penghentian darurat atau saat aplikasi dihancurkan oleh system-watchdog. Baca lebih lanjut tentang SwiftUI di materi tentang SwiftUI.

Poin Utama

  • .onDisappear — modifier SwiftUI untuk mengeksekusi kode saat View menghilang.
  • Simetri — onDisappear berpasangan dengan onAppear dan dipanggil dalam urutan terbalik.
  • Pembersihan sumber daya — skenario utama: membatalkan timer, menutup koneksi, menyimpan status.
  • Analitik — melalui onDisappear dikirim event screen close, dwell time, session end.
  • Tidak ada jaminan — onDisappear tidak dipanggil saat penghentian darurat aplikasi.

Apa itu .onDisappear?

.onDisappear — modifier View di SwiftUI yang menerima closure Void dan mengeksekusinya saat View dihapus dari hierarki. Berpasangan dengan .onAppear membentuk siklus hidup layar lengkap: kemunculan — kerja — penghilangan. Apple memperkenalkan onDisappear bersamaan dengan rilis SwiftUI di iOS 13 sebagai analog viewDidDisappear dari UIKit.

Secara sintaksis .onDisappear identik dengan onAppear: memodifikasi View apa pun dan melampirkan closure yang dipanggil oleh komponen SwiftUI saat tampilan dihapus. Berbeda dengan UIKit di mana viewDidDisappear hanya aktif setelah animasi transisi selesai, onDisappear di SwiftUI dapat dipanggil sebelum animasi selesai — saat View ditandai untuk dihapus.

Sintaks onDisappear

Sintaks dasar onDisappear sama ringkasnya dengan onAppear. Modifier tidak menerima parameter tambahan — hanya closure yang dieksekusi secara sinkron di thread utama.

swift
struct DetailView: View {
    var body: some View {
        Text("Layar Detail")
            .onDisappear {
                print("DetailView menghilang dari layar")
            }
    }
}

Cara kerja .onDisappear

Mekanisme panggilan onDisappear kebalikan dari onAppear: pertama elemen anak menerima onDisappear, kemudian induk. Aturan child-first ini memastikan bahwa sumber daya elemen anak dibebaskan sebelum sumber daya induk dibebaskan. Jika elemen anak bergantung pada data induk, ia harus dapat menyelesaikan dengan benar tanpa konteks induk.

SwiftUI memanggil onDisappear saat View dikeluarkan dari grafis render. Pemicunya bisa berupa: pop dari NavigationStack, pergantian TabView, dismiss jendela modal (sheet/fullScreenCover), perubahan View yang ditampilkan bersyarat (if/switch). Di List dan ScrollView onDisappear dipanggil saat sel di-scroll keluar dari buffer prefetch.

Urutan panggilan child-first

Urutan child-first berarti jika ada tiga View anak di VStack, onDisappear akan dipanggil pertama untuk setiap anak dalam urutan terbalik, kemudian untuk induk. Ini penting untuk pembersihan yang benar: timer anak dibatalkan sebelum ViewModel induk membebaskan sumber daya bersama.

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

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

Keluaran konsol: Child B onDisappear, Child A onDisappear, Parent onDisappear — terakhir. Urutan terbalik dibandingkan dengan onAppear memastikan rantai pembebasan yang benar.

Kapan .onDisappear dipanggil

Skenario panggilan onDisappear tergantung pada jenis kontainer. Di NavigationStack onDisappear dipicu saat pop-to-root, pop-back biasa, atau penghapusan layar dengan gesture geser (interactivePopGestureRecognizer). Di TabView pergantian tab memicu onDisappear untuk yang disembunyikan dan onAppear untuk yang ditampilkan — kedua modifier dipicu hampir bersamaan.

Di Sheet dan fullScreenCover onDisappear dipanggil saat dismiss terprogram (melalui @Environment(\.dismiss)) atau gesture geser ke bawah. Fitur penting: jika sheet telah dibuka tetapi pengguna mengganti aplikasi, onDisappear TIDAK dipanggil sampai penutupan sebenarnya.

SkenarioonDisappear dipanggilCatatan
Pop di NavigationStackYaSegera setelah animasi
Pergantian tab TabViewYaTab saat ini
Dismiss sheetYaSebelum animasi selesai
Scroll di ListYaSel keluar dari zona prefetch
Meminimalkan aplikasiTidakTidak ada jaminan panggilan
Crash/watchdog killTidakTidak dipanggil

Contoh .onDisappear

Skenario utama onDisappear — pembersihan sumber daya, penyimpanan status, dan pelacakan. Berbeda dengan onAppear, tugas onDisappear dieksekusi saat keluar dan tidak memerlukan pemeriksaan duplikasi, karena View menghilang satu kali.

Menyimpan status dan membatalkan timer

Menyimpan status di onDisappear sangat berguna untuk formulir di mana data harus disimpan saat meninggalkan layar. Timer dan langganan Combine dibatalkan di onDisappear untuk menghindari kebocoran memori saat kembali ke layar.

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

Pembatalan timer di onDisappear mencegah eksekusi kode setelah layar ditutup. Tanpa pembatalan, timer dapat mencoba memperbarui @State yang sudah tidak dimiliki View saat ini, menyebabkan runtime warning.

Melacak waktu di layar

Durasi tinggal di layar — skenario pelacakan klasik. Kami mencatat waktu di onAppear, menghitung selisih di onDisappear, dan mengirim event analitik dengan durasi sesi.

swift
struct TrackedView: View {
    @State private var appearTime: Date?
    
    var body: some View {
        Text("Layar yang Dilacak")
            .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 — perbedaan

Perbedaan utama onDisappear dengan onAppear — urutan panggilan dan jaminan pengaktifan. onAppear dipanggil saat View ditambahkan ke hierarki dan memiliki sifat panggilan ulang saat dibuat ulang. onDisappear dipanggil saat penghapusan dan dijamin hanya berfungsi pada penutupan normal, tetapi tidak dalam skenario darurat.

Menurut WWDC 2024, Apple merekomendasikan untuk menganggap onDisappear sebagai titik pembersihan, bukan titik penyimpanan data. Data yang sangat penting (pembayaran, pendaftaran) harus disimpan secara real-time, bukan saat View menghilang, karena onDisappear tidak menjamin panggilan saat aplikasi diminimalkan.

Karakteristik.onAppear.onDisappear
Saat dipanggilView ditambahkan ke hierarkiView dihapus dari hierarki
UrutanParent-firstChild-first
JaminanTinggiTidak pada penghentian darurat
Tugas utamaInisialisasiPembersihan
Panggilan ulangSaat View dibuat ulangSekali per penghilangan

Rekomendasi: gunakan onDisappear hanya untuk pembersihan dan pelacakan yang tidak kritis. Untuk menyimpan data gunakan scenePhase atau pemberitahuan applicationWillTerminate di AppDelegate.

Skenario penggunaan umum

Skenario 1: pemuatan seperti YouTube. Di layar detail video onDisappear menyimpan posisi pemutaran di UserDefaults. Saat dibuka kembali, onAppear memulihkan posisi dari UserDefaults, memberikan efek menonton berkelanjutan.

Skenario 2: pembatalan langganan Combine. Jika ViewModel menggunakan publisher Combine, onDisappear membatalkan langganan melalui cancellable?.cancel(). Ini mencegah pembaruan UI setelah meninggalkan layar, yang sangat penting untuk daftar dengan paginasi dan kueri pencarian.

Skenario 3: menutup WebSocket. Di aplikasi dengan koneksi real-time (messenger, feed harga) onDisappear menutup koneksi WebSocket untuk menghemat baterai dan trafik. Pembukaan kembali dilakukan di onAppear saat kembali ke layar.

Menutup WebSocket di onDisappear

WebSocket — sumber daya umum yang perlu ditutup saat meninggalkan layar. Dalam contoh di bawah onDisappear memutuskan socket, dan onAppear menghubungkannya kembali, memberikan penghematan trafik yang signifikan untuk aplikasi dengan banyak layar.

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

Penting: saat beralih antar tab di TabView, onDisappear tab saat ini dan onAppear tab berikutnya dipicu hampir bersamaan. Untuk WebSocket ini dapat menyebabkan siklus disconnect-connect yang menimbulkan beban tambahan. Solusi — gunakan penundaan atau periksa apakah socket diperlukan di layar berikutnya.

Pertanyaan yang Sering Diajukan

Bisakah .onDisappear tidak dipanggil?

Ya, .onDisappear tidak menjamin panggilan saat penghentian darurat aplikasi (crash, watchdog kill), meminimalkan aplikasi tanpa menutup layar, atau skenario sistem di mana aplikasi dihancurkan di latar belakang. Untuk data yang sangat penting gunakan scenePhase atau applicationWillTerminate.

Bagaimana membedakan .onDisappear dari .scenePhase?

.onDisappear dipicu saat View dihapus dari hierarki — callback lokal untuk layar tertentu. .scenePhase (melalui @Environment(\.scenePhase)) dipicu saat status seluruh aplikasi berubah: active, inactive, background. Untuk melacak waktu di layar gunakan onAppear+onDisappear, untuk menyimpan status global — scenePhase.

Mengapa .onDisappear dipanggil beberapa kali berturut-turut?

Penyebabnya — perpindahan cepat antar tab atau push/pop berulang pada layar yang sama. SwiftUI dapat membuat instance View baru, menghapus yang lama, membuat lagi — setiap kali memicu onDisappear dan onAppear. Periksa apakah Anda menggunakan .id(), .equatable() atau membuat ulang View di body induk.

Apakah .onDisappear berfungsi di SwiftUI pada macOS?

Ya, .onDisappear sepenuhnya didukung di macOS (10.15+) dengan perilaku yang sama: dipanggil saat menutup jendela, menghapus panel split view, atau dismiss jendela modal. Di macOS onDisappear juga dipanggil saat menyembunyikan jendela (hide), tidak hanya saat menutup, yang penting untuk aplikasi macOS.

Bagaimana membatalkan URLSessionTask di .onDisappear?

Simpan referensi ke URLSessionTask di @State dan panggil task.cancel() di onDisappear. Alternatifnya, gunakan modifier .task yang secara otomatis membatalkan operasi async saat View menghilang. .task lebih disukai untuk semua operasi async, termasuk URLSession.

Ringkasan

  • .onDisappear — modifier pasangan onAppear untuk pembersihan sumber daya dan pelacakan saat View menghilang.
  • Urutan child-first — View anak menerima onDisappear lebih awal dari induk untuk rantai pembebasan yang benar.
  • Tidak ada jaminan panggilan — saat crash, diminimalkan, atau penghentian sistem, onDisappear mungkin tidak berfungsi.
  • Skenario utama — pembatalan timer, penutupan WebSocket, penyimpanan status, pelacakan durasi.
  • Analitik — onDisappear mengirim event screen_close dengan perhitungan dwell time melalui Date().timeIntervalSince.
  • Untuk operasi async — gunakan .task daripada onDisappear dengan Task {}, karena .task secara otomatis membatalkan permintaan.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga