View Protocol, herhangi bir görsel arayüz bileşeninin uyması gereken temel SwiftUI protokolüdür. Apple Developer Documentation, 2024'e göre, View tek bir sözleşme tanımlar: bu protokolü uygulayan bir yapı veya sınıf, hesaplanmış bir body özelliği sağlamalıdır. Bu protokol aracılığıyla SwiftUI, basit metin etiketlerinden karmaşık navigasyon yapılarına kadar tüm ekran hiyerarşisini oluşturur.
Önemli Noktalar
View Protocol, herhangi bir görsel öğenin içeriğini nasıl tanımladığını belirleyen SwiftUI'nin merkezi protokolüdür. Her öğenin sınıflar aracılığıyla UIView'den miras aldığı UIKit'in aksine, SwiftUI protokol odaklı bir yaklaşım kullanır: View protokolüne uyan herhangi bir tür ekranda görüntülenebilir.
View protokolü, içerik döndüren tek bir hesaplanmış özellik body uygulamasını gerektirir. Ancak, bu basitliğin arkasında güçlü bir kompozisyon sistemi yatar: body, ilkeller (Text, Image, Button), kapsayıcılar (VStack, HStack, ZStack) ve özel bileşik bileşenler dahil olmak üzere View'e uyan herhangi bir türü döndürebilir.
WWDC 2023'e göre, SwiftUI uygulamalarındaki tüm ekranların %95'inden fazlası View protokolünü uygulayan yapıların kompozisyonu aracılığıyla oluşturulur. Bu, View Protocol'ü tüm SwiftUI mimarisinin temeli yapar.
SwiftUI, View'in bir değer türü (value type) (struct) olmasını gerektirir, bir sınıf değil. Bu önemli bir mimari karardır: değer türleri öngörülebilir bir yaşam döngüsüne sahiptir, paylaşılan değiştirilebilir durumları yoktur ve SwiftUI'nin hiyerarşinin hangi bölümlerinin değiştiğini ve yeniden çizilmesi gerektiğini verimli bir şekilde belirlemesine izin verir.
View'i bir sınıf yapmaya çalışırsanız, derleyici bir hata verecektir: View protokolü, değer semantiği gerektiren DynamicViewProperty protokolünden miras alır. Sınıflar View'e uyabilir, ancak bu deyimsel yaklaşımı bozar ve otomatik güncellemelerin avantajlarını kaybettirir.
body, View protokolünün tek zorunlu gereksinimidir. Ekranda görüntülenen içeriği döndüren hesaplanmış bir özelliktir. Dönüş türü some View'dır, bu da “derleyici tarafından belirlenecek, View'e uyan bir tür” anlamına gelir.
struct GreetingView: View {
var name: String
var body: some View {
VStack {
Text("Hello, \(name)!")
.font(.title)
.foregroundColor(.blue)
Button("Start") {
print("Button pressed")
}
}
}
}
body nasıl çalışır: SwiftUI, uygulama durumu her değiştiğinde ve yeniden çizim gerektiğinde body'yi çağırır. Çerçeve, yeni View ağacını eskisiyle karşılaştırır ve yalnızca gerekli değişiklikleri uygular (diffing). Bu tamamen bildirimsel bir yaklaşımdır — ne görüntülenmesi gerektiğini tanımlarsınız ve SwiftUI nasıl uygulanacağıyla ilgilenir.
Önemli bir ayrıntı: body'nin yan etkileri olmamalıdır. Uygulamanın yaşam süresi boyunca birden çok kez çağrılır ve body dış durumu değiştirirse — bu öngörülemeyen davranışa yol açar. Yan etkiler için task, onChange veya DispatchQueue kullanın.
SwiftUI bir kısıtlama getirir: body yalnızca tek bir kök öğe döndürebilir. Aynı seviyede birden çok öğe görüntülemeniz gerekiyorsa, bunları bir kapsayıcıya sarın — VStack, HStack, ZStack veya Group. @ViewBuilder'ın tanıtılmasıyla bu sınırlama daha az fark edilir hale geldi, ancak kavramsal olarak body her zaman tek bir View döndürür.
some View, Swift 5.1'de özellikle SwiftUI için tanıtılan opak tür (opaque type) sözdizimidir. Bir işlevin veya özelliğin View protokolüne uyan somut bir tür döndürdüğü, ancak çağıran kodun hangi tam türün döndürüldüğünü bilmediği ve bilmesine gerek olmadığı anlamına gelir.
Swift derleyicisi, her body uygulaması için derleme zamanında somut türü belirler, ancak onu dış dünyadan gizler. Bu, SwiftUI'nin tüm bileşenlerin tam türlerini bilerek View hiyerarşisini optimize etmesine izin verirken, geliştiriciye imzayı değiştirmeden uygulamayı değiştirme esnekliği sağlar.
struct ContentView: View {
var body: some View {
Text("Hello, World!") // Compiler knows this is Text
}
}
Neden some View ve sadece View değil? Body yalnızca View (bir protokol olarak) döndürseydi, SwiftUI derleme zamanında somut türü belirleyemezdi. Bu, varoluşsal bir kapsayıcıya (existential container) sarma için ek yük getirirdi. some View, protokolün esnekliğini korurken derleyiciye optimizasyon için yeterli bilgiyi sağlar.
Ana sınırlama, body'nin aynı türü döndürmesi gerektiğidir. Özel sarmalayıcılar (AnyView, Group veya @ViewBuilder) olmadan bir koşulun bir dalında Text ve diğerinde Image döndüremezsiniz. Derleyici bunu derleme zamanında kontrol eder: tüm olası dönüş yolları aynı türe sahip olmalıdır.
Bu sınırlamayı aşmak için @ViewBuilder (tek bir TupleView türü oluşturur), Group (tek bir tür döndürür) veya AnyView (türü siler ancak ek yük ekler) kullanılır. AnyView yalnızca diğer seçenekler mümkün olmadığında kullanılmalıdır, çünkü SwiftUI optimizasyonlarını devre dışı bırakır.
@ViewBuilder, iç içe kapsayıcılar olmadan birden çok View'i tek bir kompozisyonda birleştirmeye izin veren bir result builder'dır. @ViewBuilder, birden çok ifadeyi otomatik olarak bir demete (TupleView) sarar veya doğru dönüş türüyle koşullu mantık (If / else / switch) uygular.
struct DashboardView: View {
var isLoggedIn: Bool
@ViewBuilder
var body: some View {
if isLoggedIn {
Text("Welcome!")
.font(.largeTitle)
ProfileCard()
} else {
LoginButton()
.padding()
}
}
}
@ViewBuilder nasıl çalışır: derleyici, @ViewBuilder içindeki her kod bloğunu buildBlock, buildEither, buildOptional vb. statik yöntem çağrılarına dönüştürür. Bir blok birden çok ifade içeriyorsa — TupleView'a sarılır. Bir blok koşullu mantık içeriyorsa — derleyici ConditionalContent oluşturur ve dal türünü gizler.
@ViewBuilder bir sınırlama getirir: blok başına en fazla 10 öğe (TupleView sınırı). On öğeden fazlasını birleştirmeniz gerekiyorsa, Group, ForEach kullanın veya alt bileşenlere bölün. Bu sınırlama, Swift'in 1'den 10'a kadar her sayıda argüman için ayrı bir buildBlock aşırı yüklemesi oluşturması nedeniyle vardır.
Kompozisyon (Composition), SwiftUI'nin temel bir ilkesidir: karmaşık arayüzler küçük, yeniden kullanılabilir View bileşenlerinden oluşturulur. Her bileşen View protokolünü uygular ve ekranın kendi bölümünden sorumludur. Değiştiriciler (font, padding, foregroundColor) bir View'e uygulanır ve değiştirilmiş ayarlarla yeni bir View döndürür.
SwiftUI'deki değiştiriciler mutasyon değil, orijinal View etrafında yeni bir sarmalayıcı oluşturmadır. Her değiştirici yeni bir tür (ModifiedContent) döndürür ve SwiftUI'nin bir değiştirici ağacı oluşturmasına ve yalnızca değişen bölümleri verimli bir şekilde yeniden çizmesine izin verir. Değiştiricilerin uygulanma sırası önemlidir: farklı sıralar farklı görsel sonuçlar üretir.
Text("Hello, SwiftUI!")
.font(.title) // ModifiedContent
.padding() // ModifiedContent<..., PaddingModifier>
.background(.yellow) // ModifiedContent<..., BackgroundModifier>
.cornerRadius(8) // ModifiedContent<..., CornerRadiusModifier>
Performans optimizasyonu: SwiftUI, View'lerin somut değerlerini değil, kimlik mekanizması (id, ForEach, yapıların kararlı kimliği) aracılığıyla kimliklerini karşılaştırır. View yapısı değişmediyse — body çağrılmaz. Bu, Equatable karşılaştırması ve hiyerarşide yukarıya veri iletmek için PreferenceKey mekanizması aracılığıyla elde edilir.
Etkili kompozisyon için, karmaşık ekranların her biri kendi minimum durumuna sahip bağımsız alt bileşenlere bölünmesi önerilir. Bu, SwiftUI'nin tüm ekran yerine hiyerarşinin yalnızca değişen bölümlerini yeniden çizmesine izin verir.
Sıkça Sorulan Sorular
View Protocol, görüntülenen herhangi bir bileşenin uyması gereken SwiftUI temel protokolüdür. İçerik döndüren tek bir hesaplanmış body özelliği gerektirir. Tüm standart SwiftUI öğeleri — Text, Button, Image, VStack — bu protokolü uygular.
SwiftUI, öngörülebilir arayüz güncellemeleri için değer semantiği (value semantics) kullanır. Yapılar paylaşılan değiştirilebilir duruma sahip değildir, bu da SwiftUI'nin eski ve yeni View hiyerarşisini verimli bir şekilde karşılaştırmasına ve yalnızca değişen öğeleri yeniden çizmesine izin verir. Sınıflar bu optimizasyonu bozar.
body, some View döndürür — somut uygulamayı gizleyen opak bir tür. Aslında View'e uyan herhangi bir türü döndürür: Text, Image, VStack, özel yapılar. Derleyici, optimizasyon için derleme zamanında somut türü belirler.
some View, derleme zamanında somut türü belirlenmiş opak bir türdür. AnyView, herhangi bir View'i tek bir kapsayıcıya saran tür silmedir (type erasure). some View daha verimlidir; AnyView ek yük ekler ve yalnızca dinamik tür değişimi gerektiğinde kullanılır.
En fazla 10 öğe — bu, 1'den 10'a kadar argüman sayıları için buildBlock oluşturan TupleView sınırıdır. Daha fazla öğeye ihtiyacınız varsa, Group, ForEach, List kullanın veya alt bileşenlere bölün. Bu sınırlama Swift derleyici düzeyinde mevcuttur.
Ö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