SwiftUI — WWDC 2019'da tanıtılan, Apple ekosisteminin tüm platformlarında kullanıcı arayüzleri oluşturmak için Apple'ın bildirimsel çerçevesi. viewDidLoad ve manuel ekran güncellemeleriyle imperatif UIKit'in aksine, SwiftUI UI'yı View protokolüne uyan basit yapıların bir koleksiyonu olarak tanımlar. Swift.org'a (2025) göre SwiftUI, App Store'da yayınlanan yeni projelerin %65'inde kullanılmaktadır. Çerçeve, State ve Data Flow mekanizması aracılığıyla arayüz güncellemelerini otomatik olarak yönetir — veriler değiştiğinde, manuel reloadData çağrıları olmadan View yeniden çizilir.
Önemli Noktalar
SwiftUI — UIKit'ten kökten farklı olan Apple'ın bildirimsel UI çerçevesi. Denetleyiciler, görünümler oluşturmak ve yaşam döngülerini manuel olarak yönetmek yerine, geliştirici arayüzü bildirimler olarak tanımlar: ekranda ne olması gerektiği, nasıl oluşturulacağı değil. SwiftUI, reaktivite ilkesine dayanır: arayüz, durumun bir fonksiyonudur. Durum değiştiğinde, SwiftUI otomatik olarak tüm bağımlı View'ların body'sini yeniden hesaplar ve ekranın yalnızca değişen kısımlarını günceller. SwiftUI, iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ ve visionOS 1+'da kullanılabilir. SwiftUI kodu çapraz platformdur: tek bir dosya, minimum platform uyarlamalarıyla iPhone, iPad, Mac ve Apple Watch'ta çalışır. Apple WWDC Session 101'e (2024) göre SwiftUI, App Store'daki standart UI kalıplarının %90'ından fazlasını kapsar.
UIKit — imperatif çerçeve (2008): geliştirici bir UIViewController oluşturur, viewDidLoad'da alt görünümleri yapılandırır, UITableView için delegate/datasource uygular ve reloadData veya setNeedsLayout aracılığıyla ekranı günceller. SwiftUI, denetleyicileri basit View yapılarıyla, delegeleri bindings ve onChange ile, Auto Layout'u HStack/VStack/ZStack ve değiştiricilerle (padding, frame, offset) değiştirir. UIKit, ARC aracılığıyla manuel bellek yönetimi gerektirir; SwiftUI, referans sayımı gerektirmeyen yapılar kullanır. SwiftUI'nin performansı UIKit ile karşılaştırılabilir: çerçeve, minimum değişiklik kümeleri için bir diffing algoritması kullanır. IT Sectr'de SwiftUI, iOS 17+ hedefli yeni projeler için kullanılır; iOS 14–15 desteği olan projeler, sınırlı SwiftUI uyumluluğu nedeniyle UIKit gerektirir.
SwiftUI'de arayüz, ViewBuilder — bir dizi View'ı bir tuple veya Group'a dönüştüren result builder aracılığıyla tanımlanır. Değiştiriciler (.padding(), .font(), .foregroundColor()) orijinal nesneyi değiştirmek yerine değiştirilmiş ayarlarla yeni View'lar oluşturur. Her değiştirici yeni bir View döndürür ve zincirlemeye olanak tanır. ViewBuilder, if/else, switch, ForEach'i destekler — ayrı denetleyiciler olmadan koşullu ve döngüsel oluşturma. SwiftUI'de View bir value type'dır (struct), öngörülebilir davranış sağlar ve yarış koşullarını ortadan kaldırır.
View — tek bir gereksinimi olan bir protokol: some View türünde computed property body. View'a uyan her yapı, body'de ekranın kendi bölümünü tanımlar. some View türü, döndürülen View'ın somut türünü gizleyen opak bir dönüş türüdür (VStack, HStack, ZStack, Text, Image vb. yığınlama). Swift derleyicisi, somut türü derleme zamanında çıkarır ve tür silme olmadan doğrudan çağrıların performansını korur.
import SwiftUI
struct GreetingView: View {
var name: String
var body: some View {
VStack(spacing: 12) {
Text("Merhaba, \(name)!")
.font(.largeTitle)
.foregroundColor(.primary)
Text("SwiftUI'ye hoş geldiniz")
.font(.body)
.foregroundColor(.secondary)
}
.padding()
.background(
RoundedRectangle(cornerRadius: 12)
.fill(.ultraThinMaterial)
)
}
}GreetingView yapısı bir name parametresi alır ve dikey bir yığında iki metin bloğu görüntüler. .font, .foregroundColor, .padding ve .background değiştiricileri görünümü yapılandırır. SwiftUI, giriş parametreleri (name) her değiştiğinde body'yi çağırır — yeniden çizim yalnızca değişen kısımlar için gerçekleşir. Örnek, .ultraThinMaterial ile RoundedRectangle kullanır — SwiftUI'ye yerleşik bir bulanıklık arka planı.
@State — tek bir View'e ait yerel durumu bildiren bir property wrapper. SwiftUI, State belleğini otomatik olarak yönetir: değer değiştiğinde body yeniden çizilir, ancak yalnızca bu State'i kullanan View'lar için. State, basit türler (String, Int, Bool, enum) için gerçeğin kaynağıdır. Karmaşık veri modelleri için @State kullanmayın — bunun yerine @StateObject ve @ObservedObject kullanın. State özel olmalı ve View içinde saklanmalı, bileşenler arasında iletilmemelidir.
import SwiftUI
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 20) {
Text("Sayı: \(count)")
.font(.system(size: 48, weight: .bold))
Button(action: { count += 1 }) {
Label("Artır", systemImage: "plus.circle")
}
.buttonStyle(.borderedProminent)
}
.padding()
}
}Başlangıç count değeri = 0. Her düğmeye basıldığında count artar; SwiftUI otomatik olarak tüm CounterView'ı (tüm View'lar) yeniden çizer. UIKit'te benzer bir senaryo IBOutlet, IBAction ve manuel label.text güncellemeleri gerektirirdi. @State, belirli bir State değiştiğinde yalnızca View'ın yeniden çizilmesini sağlar — SwiftUI'nin diffing algoritması ağaçtaki minimum değişiklikleri bulur.
@Binding — bir View ile View'in sahip olmadığı veriler arasında çift yönlü bağlantı oluşturan bir property wrapper. Binding, State'e (veya başka bir gerçeğin kaynağına) bir referanstır ve alt View'in üstte depolanan değeri okumasına ve değiştirmesine olanak tanır. Binding, $ ön ekiyle belirtilir: $count, alt View'a bir Binding<Int> iletir. Binding olmadan, alt View üstün verilerini değiştiremez — yalnızca okuyabilir.
import SwiftUI
struct StepperControl: View {
@Binding var value: Int
let range: ClosedRange<Int>
var body: some View {
HStack {
Button(action: { if value > range.lowerBound { value -= 1 } }) {
Image(systemName: "minus.circle")
}
Text("\(value)")
.frame(minWidth: 40)
Button(action: { if value < range.upperBound { value += 1 } }) {
Image(systemName: "plus.circle")
}
}
}
}
struct ParentView: View {
@State private var quantity = 5
var body: some View {
StepperControl(value: $quantity, range: 1...10)
}
}ParentView, State quantity'ye sahiptir ve $quantity aracılığıyla Binding iletir. StepperControl değeri değiştirebilir ve üstteki quantity otomatik olarak senkronize olur. Binding, verilerin bir kopyası değil, gerçeğin kaynağına bir köprüdür. Üst verilerini değiştirmesi gereken özel denetimler, düzenleyiciler ve yeniden kullanılabilir bileşenler için @Binding kullanın.
@StateObject — ObservableObject'a uyan bir sınıfın örneğini oluşturmak ve sahiplenmek için property wrapper. View, yaşam döngüsü başına bir kez nesneyi oluşturur ve @Published özellikleri değiştiğinde yeniden çizilir. @ObservedObject — benzer bir sarmalayıcı, ancak View nesneye sahip değildir — nesne View dışında oluşturulur ve saklanır (bir başlatıcı aracılığıyla iletilir). Apple, View hiyerarşisinde gerçeğin kaynağı için @StateObject ve bağımlılık enjeksiyonu için @ObservedObject önerir.
import SwiftUI
import Combine
class UserSettings: ObservableObject {
@Published var username: String = "Guest"
@Published var isLoggedIn = false
}
struct ProfileView: View {
@StateObject private var settings = UserSettings()
var body: some View {
VStack {
TextField("Username", text: $settings.username)
.textFieldStyle(.roundedBorder)
Toggle("Logged In", isOn: $settings.isLoggedIn)
if settings.isLoggedIn {
Text("\(settings.username), hoş geldiniz!")
.font(.headline)
}
}
.padding()
}
}UserSettings — iki @Published özelliğine sahip bir ObservableObject. ProfileView, @StateObject aracılığıyla nesneye sahiptir. username veya isLoggedIn'deki değişiklikler ProfileView'ı otomatik olarak yeniden çizer. @Published, SwiftUI'yi değişikliklerden haberdar etmek için Combine Publisher kullanır. Alt View'lara settings iletmek için @ObservedObject kullanın:
Apple, SwiftUI'de dört Data Flow seviyesi tanımlar: @State (yerel, value type), @Binding (çift yönlü), @StateObject/@ObservedObject (ObservableObject ile reference type), @EnvironmentObject (global, ortam aracılığıyla enjekte edilir). EnvironmentObject, başlatıcıda açık aktarım olmadan tüm View hiyerarşisi boyunca veri iletmeye olanak tanır. Ek olarak, @AppStorage UserDefaults ile çalışır, @SceneStorage sahne durumuyla, @FetchRequest Core Data ile çalışır. Data Flow seviyesinin seçimi uygulama mimarisini belirler: basit ekranlar State/Binding kullanır, modüler olanlar ObservedObject kullanır, büyük ölçekli olanlar EnvironmentObject + Redux benzeri çözümler (TCA, Composable Architecture) kullanır.
| Property Wrapper | Sahiplik | Tür | Ne Zaman Kullanılır |
|---|---|---|---|
| @State | Yerel | Value (struct, enum) | Tek bir View'in basit durumu (sayaç, anahtar, metin alanı) |
| @Binding | Harici | State'e referans | Alt View, üst verilerini değiştiriyor |
| @StateObject | View Sahipliği | Reference (class) | Karmaşık veri modeli için gerçeğin kaynağı |
| @ObservedObject | Enjeksiyon | Reference (class) | View dışında oluşturulan model (init ile iletilen) |
| @EnvironmentObject | Global | Reference (class) | Tüm hiyerarşi için kullanılabilir veriler (auth, tema) |
Sıkça Sorulan Sorular
@State — value types (struct, enum, String, Int) ve tek bir View'in yerel durumu için. SwiftUI, State belleğini otomatik olarak yönetir. @StateObject — ObservableObject'a uyan reference types (class) için. @StateObject nesneye sahiptir ve @Published özellikleri değiştiğinde View'ı yeniden çizer. Basit sayaçlar için @State kullanın; iş mantığı olan modeller için @StateObject kullanın.
Evet, SwiftUI, UIHostingController (UIKit içinde SwiftUI) ve UIViewRepresentable (SwiftUI içinde UIKit) aracılığıyla UIKit ile entegre olur. UIHostingController, bir SwiftUI View'ını UIViewController içine sarar. UIViewRepresentable, SwiftUI'de UIKit bileşenlerini (MKMapView, WKWebView) kullanmaya olanak tanır. Bu, projeleri UIKit'ten SwiftUI'ye geçirmek için standart yaklaşımdır.
ViewBuilder — bir dizi View'ı TupleView, Group veya ConditionalContent türünde tek bir değere dönüştüren bir result builder (Swift 5.1). ViewBuilder, bildirimsel body içinde imperatif if/else ve switch yazmaya olanak tanır. ViewBuilder olmadan, her koşullu blok için AnyView veya Group döndürmeniz gerekirdi. ViewBuilder, body'nin View'lar arasında virgül gerektirmemesinin nedenidir.
Evet, SwiftUI, iOS 13+, iPadOS 13+, macOS 10.15+, watchOS 6+, tvOS 13+ ve visionOS 1+'ı destekler. Ancak bazı API'ler yalnızca daha yeni sürümlerde kullanılabilir: örneğin, navigationStack (iOS 16+), Observable macro (iOS 17+). Geriye dönük uyumluluk için #available ve UIKit uyarlamalarını kullanın.
Xcode Debug View Hierarchy, değiştiriciler ve çerçevelerle SwiftUI View ağacını gösterir. SwiftUI Inspector aracı (Xcode sağ paneli) değiştiricileri gerçek zamanlı olarak değiştirmeye olanak tanır. Body'deki self._printChanges() yeniden çizim nedenlerini günlüğe kaydeder. SwiftUI şablonuyla Instruments, View performansını izler ve aşırı yeniden çizimleri belirler.
Ö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