@Binding, başka bir bileşene ait verilere referans oluşturan SwiftUI'deki bir Property Wrapper'dır. Binding değeri kendisi saklamaz — yalnızca $ projeksiyonu aracılığıyla mevcut doğruluk kaynağına erişim sağlar. Apple Developer Documentation (2025)'a göre Binding, verilere doğrudan sahip olmadan üst ve alt görünüm arasında reaktif çift yönlü iletişim sağlar. @Binding, değiştirilebilir durumu hiyerarşide aşağıya aktarmak için ana mekanizmadır.
Önemli Noktalar
@Binding, üst görünümde saklanan bir özellik ile alt bileşen arasında çift yönlü bağlantı oluşturan bir Property Wrapper'dır. Binding ve @State arasındaki temel fark: Binding verilere sahip değildir. Değerleri yalnızca gerçek kaynak — @State, @StateObject veya üst görünümdeki başka bir Binding — aracılığıyla okur ve yazar. Binding olmadan, alt görünümler geri çağırma veya temsilciler olmadan atanın durumunu değiştiremezdi.
Binding, iki özelliğe sahip bir yapı olarak uygulanır: wrappedValue (mevcut değer) ve projectedValue ($ aracılığıyla erişilebilen Binding'in kendisi). Alt görünüm Binding aracılığıyla wrappedValue'ı değiştirdiğinde, SwiftUI değişikliği veri kaynağına iletir ve bağımlı tüm görünümleri yeniden çizer. Bu, mevcut güncelleme döngüsü içinde eşzamanlı olarak gerçekleşir.
Önemli bir özellik: @Binding tek seviyeli aktarımla sınırlı değildir. Binding birden çok hiyerarşi seviyesi boyunca aktarılabilir — her alt bileşen aynı veri kaynağına bir referans alır. Herhangi bir seviyedeki değişiklik, bağlı tüm görünümlerin tek bir güncellemesini tetikler.
@Binding aracılığıyla çift yönlü bağlama mekanizması, Property Wrapper projeksiyonları üzerine inşa edilmiştir. Bir üst görünüm @State var value: T bildirdiğinde, SwiftUI otomatik olarak Binding<T> türünde $value projeksiyonunu oluşturur. $value'yu @Binding var value: T içeren bir alt bileşene aktararak, her iki görünümü aynı bellek hücresine bağlarsınız. Alt görünümde Binding aracılığıyla yapılan herhangi bir yazma, her iki bileşenin de yeniden çizilmesini tetikler.
struct SliderContainer: View {
@State private var value: Double = 0.5
var body: some View {
VStack {
Text("Value: \(value)")
SliderView(value: $value)
}
}
}
struct SliderView: View {
@Binding var value: Double
var body: some View {
Slider(value: $value, in: 0...1)
}
}
Örnekte, SliderContainer @State value'ya sahiptir ve SliderView Binding'i $value aracılığıyla alır. SliderView içindeki Slider bu Binding'e bağlıdır. Kaydırıcı sürüklendiğinde, Slider Binding aracılığıyla değeri değiştirir, bu da SliderContainer'daki @State'i otomatik olarak günceller ve her iki görünüm de geçerli sayıyı görüntüler. Tüm zincir tek bir geri çağırma veya bildirim olmadan çalışır.
@StateObject veya @ObservedObject'ten Binding oluşturmak için aynı projeksiyon kullanılır: $object.property Binding<PropertyType> verir. Bu, nesnenin tamamını aktarmadan ObservableObject'in bireysel özelliklerinin alt görünümlere aktarılmasını sağlar. Bu yaklaşım daha dar bir bağlantı sağlar ve gereksiz yeniden çizmeleri önler.
SwiftUI'den önce, değişiklikleri hiyerarşide yukarı aktarmanın standart yolu geri çağırmalar ve temsilcilerdi: üst görünüm bir closure aktarır, alt bileşen değişiklikte onu çağırırdı. @Binding daha az kod ve daha bildirimsel bir sözdizimi ile bir alternatif sunar. Bir tamamlama closure'ı aktarmak yerine, sadece $stateValue'yu aktarırsınız.
| Kriter | @Binding | Geri Çağırmalar |
|---|---|---|
| Kod | Bir ek açıklama + $ | Closure + çağrı |
| Çok seviyeli | Otomatik | Closure zinciri |
| Test | Binding(value:constant) | Mock closure'lar |
| Okunabilirlik | Yüksek | Orta |
| Esneklik | Sadece veri | Herhangi bir mantık |
Alt görünümün yalnızca bir değeri okuması ve değiştirmesi gerektiğinde @Binding kullanın. Değişiklikte yan etkiler gerekiyorsa (doğrulama, günlükleme, ağ isteği), Binding'i bir geri çağırma ile birleştirin: veriler için Binding ve olaylar için bir closure aktarın. Örneğin, bir TextField bir Binding'e bağlanabilirken onChange doğrulamayı tetikler.
@Binding birkaç tipik senaryoda kullanılır. Birincisi — özel kontroller: anahtarlar, kaydırıcılar, renk seçiciler ve diğer etkileşimli öğeler çift yönlü senkronizasyon için Binding kabul eder. İkincisi — modal pencereler: sayfa görüntüleme bayrağı Binding olarak aktarılır ve alt görünümün presentationMode veya doğrudan ayarlama yoluyla kendini kapatmasına izin verir.
Üçüncü desen — ayrılmış formlar. Bir form birçok alandan oluşuyorsa, her alan değeri için bir Binding kabul eden ayrı bir bileşene çıkarılabilir. Bu, alanların farklı formlar arasında test edilmesini ve yeniden kullanılmasını basitleştirir. Üst bileşen, tüm form modelinin tek sahibi olarak kalır.
struct FormField: View {
let title: String
@Binding var text: String
var body: some View {
VStack(alignment: .leading) {
Text(title).font(.caption)
TextField("Enter \(title.lowercased())", text: $text)
.textFieldStyle(.roundedBorder)
}
}
}
FormField bileşeni bir başlık ve bir dizeye Binding kabul eder. Bir etiket ve aktarılan Binding'e bağlı bir TextField görüntüler. Herhangi bir form, her alan için $property aktararak FormField'ı birden çok kez kullanabilir. Bu, işaretleme tekrarını azaltır ve metin alanı stilini merkezileştirir.
SwiftUI, Binding(get:set:) başlatıcısı aracılığıyla manuel olarak Binding oluşturmayı sağlar. Bu, bir değeri okurken veya yazarken mantık eklenmesi gerektiğinde kullanışlıdır. Örneğin, kaydetmeden önce bir sayıyı biçimlendiren bir Binding veya her değişiklikte değeri uzak bir sunucuyla senkronize eden bir Binding oluşturulabilir.
struct ValidatedField: View {
@State private var email: String = ""
var emailBinding: Binding<String> {
.init(
get: { email },
set: { email = $0.lowercased().trimmingCharacters(in: .whitespaces) }
)
}
var body: some View {
TextField("Email", text: emailBinding)
}
}
Listelemede, özel emailBinding her değişiklikte metni otomatik olarak küçük harfe dönüştürür ve boşlukları kırpar. TextField, $email'e doğrudan bağlanmak yerine bu Binding'i kullanır. Bu yaklaşım, kodu onChange işleyicileriyle karmaşıklaştırmadan doğrulama ve veri dönüşümünü Binding içinde merkezileştirir.
İlk ve en yaygın hata, Binding yerine değer aktarmaktır. Bir alt bileşen @Binding var text: String bildirirse ve üst görünüm text'i ($ olmadan) aktarırsa, derleyici bir hata verir: Cannot convert value of type 'String' to expected argument type 'Binding<String>'. Çözüm — aktarırken her zaman $ önekini kullanın: $text.
İkinci hata — salt okunur verilerde Binding. Alt görünüm yalnızca bir değer okumak zorundaysa, @Binding kullanmayın — üst görünümden basit bir let veya @State yeterlidir. Binding yazma yeteneğini ima eder ve aşırı değişiklik izinleri hata ayıklamayı karmaşıklaştırır ve en az ayrıcalık ilkesini ihlal eder.
Üçüncü sorun — üretimde Binding.constant. Binding.constant(value) geri bildirim olmadan sahte bir bağlama oluşturur — değişiklikler yok sayılır. constant'ı yalnızca prototipleme ve önizlemeler (Xcode Previews) için kullanın, ancak gerçek kodda asla. Testler için kontrollü davranışla Binding(get:set:) kullanın.
Sıkça Sorulan Sorular
@State verilere sahiptir ve bunların yığında saklanmasını yönetir. @Binding sahiplik olmadan yalnızca mevcut duruma referans verir. @State her zaman özeldir, @Binding alt görünümün bir giriş parametresidir.
Evet, Binding(get:set:) başlatıcısı veya Binding.constant(value) aracılığıyla. Binding ayrıca @StateObject'ten $object.$property projeksiyonu ve Publisher'dan Subscribe içinde Binding(get:set:) aracılığıyla da elde edilebilir.
@Binding bir zincir aracılığıyla aktarılır: her ara bileşen @Binding bildirir ve $ aracılığıyla daha ileri aktarır. Tüm seviyeler, kök görünümdeki aynı veri kaynağına başvurur.
Binding.constant sessiz bir sarmalayıcı oluşturur — ayarlayıcı yeni değerleri yok sayar. Alt bileşenden geri bildirim gerekmeyen prototipleme ve SwiftUI Previews için tasarlanmıştır.
Evet, Binding<T?> desteklenir. Binding<String?> aktarırsanız, alt görünüm nil ayarlayabilir. Bu, isteğe bağlı form alanları veya sıfırlama seçeneği olan durumlar için kullanışlıdı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