.onDisappear: çalışma prensibi ve SwiftUI'de kullanımı

Yazar: IT Sectr Yayınlanma: 2026-06-26 Okuma süresi: 10 dk

.onDisappear, bir View arayüz hiyerarşisinden kaldırıldığında bir closure çalıştıran SwiftUI değiştiricisidir. Çağrı, ekran kapatıldığında, sekme değiştirildiğinde, modal pencere kapatıldığında veya bir öğe görünürlük dışına kaydırıldığında gerçekleşir. Apple Developer Documentation'a (2026) göre onDisappear, çökme senaryolarında veya uygulama sistem watchdog tarafından sonlandırıldığında çağrıyı garanti etmez. SwiftUI hakkında daha fazla bilgi için SwiftUI makalesine bakın.

Önemli Noktalar

  • .onDisappear — View kaybolduğunda kod çalıştırmak için SwiftUI değiştiricisi.
  • Simetri — onDisappear, onAppear'ın eşidir ve ters sırada çağrılır.
  • Kaynak temizliği — ana senaryo: zamanlayıcıları iptal etme, bağlantıları kapatma, durumu kaydetme.
  • Analitik — onDisappear aracılığıyla ekran kapatma, bekleme süresi ve oturum sonu olayları gönderilir.
  • Garanti yok — uygulama çöktüğünde onDisappear çağrılmaz.

.onDisappear nedir?

.onDisappear, SwiftUI'de bir Void closure alan ve View hiyerarşiden kaldırıldığında bunu çalıştıran bir View değiştiricisidir. .onAppear ile birlikte bir ekranın tam yaşam döngüsünü oluşturur: görünme — çalışma — kaybolma. Apple, onDisappear'ı SwiftUI ile birlikte iOS 13'te UIKit'teki viewDidDisappear'ın benzeri olarak tanıttı.

Sözdizimsel olarak .onDisappear, onAppear ile aynıdır: herhangi bir View'i değiştirir ve SwiftUI oluşturucusunun view kaldırıldığında çağırdığı bir closure ekler. Geçiş animasyonunun tamamlanmasından sonra tetiklenen UIKit'teki viewDidDisappear'ın aksine, SwiftUI'de onDisappear animasyon bitmeden — View'in kaldırılmak üzere işaretlendiği anda çağrılabilir.

onDisappear sözdizimi

Temel sözdizimi onDisappear'ın onAppear kadar kısadır. Değiştirici ek parametre almaz — yalnızca ana iş parçacığında eşzamanlı olarak çalışan closure.

swift
struct DetailView: View {
    var body: some View {
        Text("Detail Screen")
            .onDisappear {
                print("DetailView ekrandan kayboldu")
            }
    }
}

.onDisappear nasıl çalışır

Çağrı mekanizması onDisappear'ın onAppear'ın tersidir: alt öğeler önce onDisappear alır, sonra üst öğe. Bu child-first kuralı, üst kaynakları serbest bırakılmadan önce alt kaynakların serbest bırakılmasını sağlar. Bir alt öğe üst verilere bağımlıysa, üst bağlamı olmadan doğru şekilde sonlanabilmelidir.

SwiftUI, View oluşturma grafiğinden kaldırıldığında onDisappear'ı çağırır. Tetikleyiciler şunları içerir: NavigationStack'ten pop, TabView değiştirme, modal kapatma (sheet/fullScreenCover) veya koşullu olarak oluşturulan View (if/switch). List ve ScrollView'da, bir hücre önceden yükleme arabelleğinin dışına kaydırıldığında onDisappear çağrılır.

Child-first çağrı sırası

Child-first sırası, bir VStack'te üç alt View varsa, onDisappear'ın önce her alt için ters sırada, sonra üst için çağrıldığı anlamına gelir. Bu, doğru temizlik için kritiktir: üst ViewModel paylaşılan kaynakları serbest bırakmadan önce alt zamanlayıcılar iptal edilir.

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

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

Konsol çıktısı: Child B onDisappear, Child A onDisappear, Parent onDisappear — son. onAppear'a kıyasla ters sıra, doğru temizleme zincirini garanti eder.

.onDisappear ne zaman çağrılır

Çağrı senaryoları onDisappear'ın kapsayıcı türüne bağlıdır. NavigationStack'te onDisappear, pop-to-root, normal pop-back veya kaydırarak (interactivePopGestureRecognizer) ekran kapatmada tetiklenir. TabView'da sekme değiştirme, gizli sekme için onDisappear'ı ve gösterilen sekme için onAppear'ı çağırır — her iki değiştirici neredeyse aynı anda tetiklenir.

Sheet ve fullScreenCover'da onDisappear, programatik kapatmada (@Environment(\.dismiss) aracılığıyla) veya aşağı kaydırma hareketinde çağrılır. Önemli bir ayrıntı: bir sheet açıldıysa ancak kullanıcı uygulamayı değiştirdiyse, onDisappear fiili kapanışa kadar çağrılmaz.

SenaryoonDisappear çağrılırNot
NavigationStack'te PopEvetAnimasyondan hemen sonra
TabView sekme değişimiEvetMevcut sekme
Sheet kapatmaEvetAnimasyon tamamlanmadan önce
List'te kaydırmaEvetHücre ön yükleme bölgesinden çıktı
Uygulamayı küçültmeHayırÇağrı garantisi yok
Çökme/watchdog killHayırÇağrılmaz

.onDisappear örnekleri

Ana kullanım durumları onDisappear'ın kaynak temizliği, durum kaydetme ve izlemedir. onAppear'ın aksine, onDisappear görevleri çıkışta çalıştırılır ve yinelenme kontrolü gerektirmez çünkü View bir kez kaybolur.

Durum kaydetme ve zamanlayıcı iptali

Durum kaydetme onDisappear'da, ekrandan ayrılırken verilerin kaydedilmesi gereken formlar için özellikle kullanışlıdır. Zamanlayıcılar ve Combine abonelikleri, ekrana dönerken sızıntıları önlemek için onDisappear'da iptal edilir.

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

Zamanlayıcı iptali onDisappear'da, ekran zaten kapatıldıktan sonra kod çalışmasını önler. İptal edilmezse, zamanlayıcı artık mevcut View'e ait olmayan @State'i güncellemeye çalışarak çalışma zamanı uyarısına neden olabilir.

Ekranda kalma süresi izleme

Ekranda kalma süresi klasik bir izleme senaryosudur. onAppear'da zamanı kaydedin, onDisappear'da farkı hesaplayın ve oturum süresiyle birlikte bir analitik olayı gönderin.

swift
struct TrackedView: View {
    @State private var appearTime: Date?
    
    var body: some View {
        Text("Tracked 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 — farklar

Temel fark onDisappear ve onAppear arasındaki çağrı sırası ve yürütme garantileridir. onAppear, View hiyerarşiye eklendiğinde çağrılır ve yeniden oluşturmada tekrar çağrılabilir. onDisappear kaldırmada çağrılır ve yalnızca normal kapanışta tetiklenmesi garanti edilir, çökme senaryolarında değil.

WWDC 2024'e göre Apple, onDisappear'ı bir veri kayıt noktası değil, bir temizlik noktası olarak ele almayı önerir. Kritik veriler (ödemeler, kayıtlar) View kaybolduğu anda değil, gerçek zamanlı olarak kaydedilmelidir çünkü uygulama küçültüldüğünde onDisappear garanti edilmez.

Özellik.onAppear.onDisappear
Çağrı anıView hiyerarşiye eklendiView hiyerarşiden kaldırıldı
SıraParent-firstChild-first
GarantiYüksekÇökmelerde yok
Ana görevBaşlatmaTemizlik
Tekrarlanan çağrıView yeniden oluşturmadaKaybolma başına bir kez

Öneri: onDisappear'ı yalnızca kritik olmayan temizlik ve izleme için kullanın. Veri kalıcılığı için AppDelegate'te scenePhase veya applicationWillTerminate bildirimlerini kullanın.

Tipik kullanım senaryoları

Senaryo 1: YouTube benzeri oynatma. Video detay ekranında onDisappear, oynatma konumunu UserDefaults'a kaydeder. Yeniden açıldığında onAppear, UserDefaults'tan konumu geri yükleyerek sürekli bir izleme deneyimi sağlar.

Senaryo 2: Combine aboneliğini iptal etme. Bir ViewModel Combine yayıncıları kullanıyorsa, onDisappear cancellable?.cancel() ile aboneliği iptal eder. Bu, ekrandan ayrıldıktan sonra UI güncellemelerini önler; sayfalama içeren listeler ve arama sorguları için özellikle önemlidir.

Senaryo 3: WebSocket kapatma. Gerçek zamanlı bağlantıları olan uygulamalarda (mesajlaşma, kotasyon akışları) onDisappear, pil ve veri tasarrufu için WebSocket bağlantısını kapatır. Ekrana dönüşte onAppear'da yeniden bağlantı gerçekleşir.

onDisappear'da WebSocket kapatma

WebSocket, ekrandan ayrılırken kapatılması gereken tipik bir kaynaktır. Aşağıdaki örnekte onDisappear soket bağlantısını keser ve onAppear yeniden bağlanır; bu, birden çok ekranlı uygulamalar için önemli veri tasarrufu sağlar.

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

Önemli: TabView sekmeleri arasında geçiş yaparken, mevcut sekmelerin onDisappear'ı ve sonraki sekmelerin onAppear'ı neredeyse aynı anda tetiklenir. WebSocket için bu, gereksiz yük oluşturan bir bağlantı kesme-yeniden bağlanma döngüsüne neden olabilir. Çözüm, bir gecikme kullanmak veya sonraki ekranda sokete ihtiyaç olup olmadığını kontrol etmektir.

Sıkça Sorulan Sorular

.onDisappear çağrılmayabilir mi?

Evet, .onDisappear uygulama çökmesi (crash, watchdog kill), ekranı kapatmadan uygulamayı küçültme veya uygulamanın arka planda sonlandırıldığı sistem senaryolarında çağrıyı garanti etmez. Kritik veriler için scenePhase veya applicationWillTerminate kullanın.

.onDisappear'ı .scenePhase'den nasıl ayırt ederim?

.onDisappear, View hiyerarşiden kaldırıldığında tetiklenir — belirli bir ekran için yerel bir geri çağrı. .scenePhase (@Environment(\.scenePhase) aracılığıyla) tüm uygulama durumu değiştiğinde tetiklenir: active, inactive, background. Ekran süresi izleme için onAppear+onDisappear ve küresel durum kalıcılığı için scenePhase kullanın.

.onDisappear neden art arda birden çok kez çağrılır?

Neden, hızlı sekme değiştirme veya aynı ekranın tekrarlanan push/pop'udur. SwiftUI yeni bir View örneği oluşturabilir, eskisini kaldırabilir, tekrar oluşturabilir — her seferinde onDisappear ve onAppear'ı çağırarak. .id(), .equatable() kullanıp kullanmadığınızı veya üst gövdede View'i yeniden oluşturup oluşturmadığınızı kontrol edin.

macOS'ta SwiftUI'de .onDisappear çalışır mı?

Evet, .onDisappear macOS'ta (10.15+) aynı davranışla tam olarak desteklenir: pencere kapatıldığında, split view paneli kaldırıldığında veya modal kapatıldığında çağrılır. macOS'ta onDisappear, pencere gizlendiğinde de çağrılır (yalnızca kapatıldığında değil), bu macOS uygulamaları için dikkate alınması önemlidir.

.onDisappear'da URLSessionTask nasıl iptal edilir?

@State'te URLSessionTask'e bir referans kaydedin ve onDisappear'da task.cancel()'ı çağırın. Alternatif olarak, View kaybolduğunda async işlemi otomatik olarak iptal eden .task değiştiricisini kullanın. .task, URLSession dahil tüm async işlemler için tercih edilir.

Özet

  • .onDisappear — View kaybolduğunda kaynak temizliği ve izleme için onAppear'ın eş değiştiricisi.
  • Child-first sırası — alt View'ler, doğru temizleme zinciri için üst View'den önce onDisappear alır.
  • Çağrı garantisi yok — çökme, küçültme veya sistem sonlandırmasında onDisappear tetiklenmeyebilir.
  • Ana kullanım durumları — zamanlayıcı iptali, WebSocket kapatma, durum kaydetme, süre izleme.
  • Analitik — onDisappear, Date().timeIntervalSince ile hesaplanan kalma süresiyle screen_close olayları gönderir.
  • Async işlemler için — Task {} ile onDisappear yerine .task kullanın çünkü .task istekleri otomatik olarak iptal eder.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun