.onAppear, bir View arayüz hiyerarşisine eklendiğinde bir closure çalıştıran SwiftUI değiştiricisidir. Çağrı, örneğin ekranda görünmesi başına bir kez gerçekleşir ve veri yükleme, animasyon başlatma ve analitik olayları gönderme için ana nokta görevi görür. Apple Developer Documentation'ya (2026) göre onAppear, ilk renderdan önce yürütmeyi garanti eder, ancak View bellekte kalırsa her tekrarlanan görüntülemede çağrıyı garanti etmez. SwiftUI hakkında daha fazla bilgi için SwiftUI makalesine bakın.
Önemli Noktalar
.onAppear, SwiftUI'de bir Void closure alan ve View ekranda görünür hale geldiğinde onu çalıştıran bir View değiştiricisidir. Bu değiştirici, .onDisappear ve .task ile birlikte SwiftUI bileşen yaşam döngüsü sisteminin bir parçasıdır. Apple, onAppear'ı UIKit'teki viewDidLoad'ın yerine geçmesi için SwiftUI'nin iOS 13 ve watchOS 6 sürümüyle birlikte tanıttı.
Sözdizimsel olarak, .onAppear herhangi bir View'i değiştirir ve ekli bir eylemle aynı View'i döndürür. SwiftUI birleştiricisi, view hiyerarşiye eklendiğinde ve render aşamasını geçtiğinde iletilen closure'u bir kez çağırır. Bir View kaldırılır ve tekrar eklenirse (örneğin, bir listede kaydırma yaparken), onAppear yeniden çağrılır — bu davranış genellikle beklenmedik hataların kaynağı olur.
Değiştiricinin temel sözdizimi minimaldir: parametresiz onAppear. SwiftUI, öncelik veya animasyon geçirmek için bir yol sunmaz — closure, renderdan hemen sonra ana iş parçacığında senkron olarak çalıştırılır.
struct ContentView: View {
var body: some View {
Text("Hello, SwiftUI!")
.onAppear {
print("View appeared on screen")
}
}
}
Sınırlamalar: onAppear, async/await'i doğrudan desteklemez. Closure içindeki asenkron işlemler için Task {} veya Task.detached aracılığıyla çağrılan ayrı bir async/await işlevi gerekir. Bu, onAppear'ı .task değiştiricisine kıyasla ağ istekleri için daha az kullanışlı hale getirir.
.onAppear, layout+render aşamasında SwiftUI render hattına gömülüdür. SwiftUI View gövdesini hesapladığında ve hiyerarşide bir değişiklik algıladığında, yeni eklenen tüm view'lar için onAppear geri çağrılarını tetikler. Çağrı sırası iç içe geçmeyi takip eder: önce ebeveyn onAppear, sonra alt öğeler.
SwiftUI'nin önemli bir özelliği, onAppear'ın fiziksel ekran görünümüne bağlı olmamasıdır. Değiştirici, bir View kullanıcıya görünür olsun veya olmasın (örneğin, ScrollView'da ekran dışında) hiyerarşiye eklendiğinde çağrılır. Bu, SwiftUI'yi viewWillAppear'ın yalnızca gerçek görünümde tetiklendiği UIKit'ten ayırır.
Çağrı sırası ebeveyn-ilk kuralını takip eder: VStack veya NavigationView önce onAppear alır, ardından sırayla her alt öğe alır. Bu, paylaşılan kaynakların başlatılması için kritiktir: alt öğeler ebeveyn tarafından yüklenen verilere bağımlıysa, Optional aracılığıyla kullanılabilirliği kontrol etmelidir.
struct ParentView: View {
var body: some View {
VStack {
ChildView()
ChildView()
}
.onAppear {
print("Parent onAppear — first")
}
}
}
struct ChildView: View {
var body: some View {
Text("Child")
.onAppear {
print("Child onAppear")
}
}
}
Konsol çıktısı şöyle olacaktır: Parent onAppear — önce, ardından sırayla iki kez Child onAppear. Bu davranış Apple tarafından garanti edilir ve tüm SwiftUI sürümlerinde (iOS 13–18) kararlıdır.
.onAppear'ın kapsayıcıya ve gezinmeye bağlı olarak birkaç çağrı senaryosu vardır. NavigationStack'te onAppear, her yeni denetleyici push'unda ve pop'ta — kök denetleyici için tetiklenir. TabView'de, sekme değiştirme görüntülenen sekme için onAppear'ı ve gizli sekme için onDisappear'ı çağırır.
List ve ScrollView'da onAppear, görünür alana giren veya önceden render tamponunda bulunan hücreler için çağrılır. iOS 18, kaydırmadan 2–3 ekran önceki hücreler için onAppear'ı çağırabilen bir ön getirme mekanizması ekledi — bu algıyı hızlandırır ancak gereksiz ağ isteklerini tetikleyebilir.
NavigationStack (iOS 16+), ekran yığınını NavigationView'dan farklı yönetir. Yeni bir ekran push'landığında, onAppear yalnızca yeni ekranda tetiklenirken, mevcut ekran gerçek kaldırmaya kadar onDisappear almaz. Pop'ta ters süreç gerçekleşir: terk edilen ekranda onDisappear, geri dönen ekranda onAppear.
| Senaryo | onAppear | onDisappear |
|---|---|---|
| Push | Yeni ekran | Hayır (ekran yığında kalır) |
| Pop | Geri dönen ekran | Terk edilen ekran |
| Sekme değiştirme | Yeni sekme | Eski sekme |
| Sheet kapatma | Ebeveyn ekranı | Açılan sheet |
Pratik uygulamalar üç ana kategoriyi kapsar: veri yükleme, animasyon başlatma ve analitik gönderme. Her senaryo, yinelenen çağrıları ve bellek sızıntılarını önlemek için SwiftUI yaşam döngüsü özelliklerinin dikkate alınmasını gerektirir.
Veri yükleme, onAppear'ın en yaygın kullanım durumudur. Closure içinde, async çağrı için bir Task oluşturulur ve sonuç @State veya @StateObject'te saklanır. Bir isLoading bayrağı veya nil kontrolü kullanarak verilerin daha önce yüklenip yüklenmediğini kontrol etmek önemlidir.
struct ProfileView: View {
@StateObject private var viewModel = ProfileViewModel()
var body: some View {
VStack {
if viewModel.isLoading {
ProgressView()
} else {
Text(viewModel.userName)
}
}
.onAppear {
guard viewModel.userName == nil else { return }
Task {
await viewModel.loadProfile()
}
}
}
}
Yeniden getirmeye karşı koruma kritik bir uygulamadır. SwiftUI View'i yeniden oluşturursa (örneğin, ekran döndürmede), onAppear koruma olmadan yeniden tetiklenir. Bir alternatif, önceki isteği otomatik olarak iptal eden .task değiştiricisidir.
Giriş animasyonu, withAnimation veya animation değiştiricisi aracılığıyla animasyonu tetikleyen durum değişkenlerini değiştirmek için onAppear'ı kullanır. Tipik desen: başlangıç durumu (opacity 0, offset 100), görünümde son duruma (opacity 1, offset 0) geçiş.
struct AnimatedCard: View {
@State private var isVisible = false
var body: some View {
RoundedRectangle(cornerRadius: 12)
.fill(Color.blue)
.opacity(isVisible ? 1 : 0)
.offset(y: isVisible ? 0 : 50)
.animation(.spring(), value: isVisible)
.onAppear {
withAnimation(.spring().delay(0.3)) {
isVisible = true
}
}
}
}
0,3 saniyelik gecikme, ekranda birden çok kart varsa sıralı bir görünüm efekti oluşturur. Animasyonlu öğeler listesi için, öğe indeksini gecikme çarpanı olarak kullanın.
.task, iOS 15'te eklenen ve onAppear'daki asenkron işlemler sorununu çözen bir SwiftUI değiştiricisidir. onAppear'ın aksine .task bir async closure kabul eder, yaşam döngüsünü otomatik olarak yönetir ve View kaybolduğunda onu iptal eder. onAppear senkron olarak çalışırken, .task asenkron bir işlem başlatır ve SwiftUI'nin onDisappear'da onu iptal etmesine izin verir.
Temel fark iptal yönetimidir. .task bir async işlem oluşturduğunda, SwiftUI Task'a bir referans kaydeder ve View hiyerarşiden kaldırıldığında otomatik olarak cancel() çağrısı yapar. İçinde Task {} bulunan onAppear, çalışan işlemi iptal etmez — View kaybolduktan sonra bile yürütülmeye devam eder, bu da yarış koşullarına veya serbest bırakılmış bir örneğe yazmaya neden olabilir.
| Özellik | .onAppear | .task |
|---|---|---|
| iOS sürümü | iOS 13+ | iOS 15+ |
| Async desteği | Yalnızca Task {} ile | Yerel async/await |
| Otomatik iptal | Hayır | View kaybolduğunda |
| Yeniden çağrı | Her görünümde | Varsayılan olarak bir kez |
| Senkron kod | Evet | Yalnızca async |
Değiştirici seçimi: senkron eylemler (animasyonlar, analitik, günlük kaydı) için onAppear kullanın. Asenkron veri yükleme (API, Core Data, dosya sistemi) için .task tercih edin — daha güvenli ve temizdir.
Hata 1: View yeniden oluşturma nedeniyle birden çok çağrı. SwiftUI View gövdesini yeniden oluşturduğunda (durum değişikliği, ekran döndürme), onAppear yeniden çağrılabilir. Çözüm — bir yükleme bayrağı ekleyin veya gereksiz yeniden çizimleri önlemek için .equatable() kullanın. SwiftLee'ye (2025) göre, üretimdeki SwiftUI hatalarının %40'ı yinelenen onAppear çağrılarıyla ilgilidir.
Hata 2: Güçlü referans yoluyla bellek sızıntısı. onAppear closure'ı zayıf bir referans olmadan self'i yakalarsa, View ile bir tutma döngüsü oluşturur. SwiftUI, View kaybolduğunda yakalanan nesnelerin sıfırlanmasını garanti etmez. ViewModel veya hizmetler için yakalama listesi [weak self] kullanın.
Hata 3: Arka plan iş parçacığında yürütme. onAppear ana iş parçacığında çalışır — bu UI işlemleri için doğrudur. Ancak onAppear içinde bir Task başlatırsanız, @State güncellemesinin MainActor.run aracılığıyla gerçekleştiğinden emin olun. Swift 5.9 ve üzeri otomatik olarak MainActor'a döner, ancak @MainActor'ı açıkça belirtmek daha iyidir.
Yükleme bayrağıyla desen, yinelemeye karşı korumanın en güvenilir yoludur. Bayrağı @State veya @StateObject'te saklayın ve yalnızca manuel güncellemede sıfırlayın. Bir alternatif, onAppear yerine .task kullanmaktır: .task, async işlem zaten çalışıyorsa varsayılan olarak yeniden çizimde yeniden başlamaz.
struct SafeView: View {
@State private var hasAppeared = false
@State private var items: [Item] = []
var body: some View {
List(items, id: \.id) { item in
Text(item.name)
}
.onAppear {
guard !hasAppeared else { return }
hasAppeared = true
Task {
items = await DataService.shared.fetchItems()
}
}
}
}
Sıkça Sorulan Sorular
viewDidLoad, UIViewController'ın ömrü boyunca bir kez çağrılır, görünürlükten bağımsız olarak. .onAppear, bir View hiyerarşiye her eklendiğinde çağrılır — bir View kaldırılır ve tekrar eklenirse, onAppear yeniden tetiklenir. NavigationView'da viewDidLoad başlatma sırasında çağrılırken, onAppear her ekran görüntülemesinde çağrılır.
Evet, Task { await asyncFunction() } sarmalayıcısı aracılığıyla. Ancak, async işlemler için .task tercih edilir çünkü iptali otomatik olarak yönetir ve manuel olarak Task oluşturmayı gerektirmez. .task ayrıca View kaybolduğunda iptali garanti ederek sızıntıları önler.
Sebep, @State, @Published veya ata yapılandırmasındaki değişiklikler nedeniyle View gövdesinin yeniden oluşturulmasıdır. SwiftUI, gözlemlenebilir herhangi bir özellikteki değişikliklere yanıt olarak bir View'i yeniden çizebilir. Ek olarak, LazyVStack ve List, görünür alana yaklaşan hücreler için onAppear'ı çağırır ve yukarı kaydırırken tekrar çağırır.
Evet, .onAppear tüm SwiftUI platformlarında kullanılabilir: iOS 13+, watchOS 6+, tvOS 13+, macOS 10.15+. Davranış aynıdır: View hiyerarşiye eklendiğinde değiştirici çağrılır. WatchOS'ta onAppear, uygulama bekleme durumundan etkinleştirildiğinde tetiklenir, bu nedenle tasarımda dikkate alınması gerekir.
.onAppear parametre kabul etmez — yalnızca bir Void closure. Parametre iletmek için, dış değişkenleri yakalayan bir closure kullanın. Alternatif bir yaklaşım, ViewModifier veya .onChange eşdeğeri aracılığıyla parametrelerle özel bir onAppear değiştiricisi oluşturmaktır.
Özet
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.
Ayrıca okuyun