A @Binding egy Property Wrapper a SwiftUI-ban, amely referenciát hoz létre egy másik komponens által birtokolt adatokra. A Binding nem tárolja az értéket önállóan — csak hozzáférést biztosít a meglévő igazságforráshoz a $ projekción keresztül. A Apple Developer Documentation (2025) szerint a Binding reaktív kétirányú kapcsolatot biztosít a szülő- és gyermeknézet között anélkül, hogy közvetlenül birtokolná az adatokat. @Binding a kulcsmechanizmus a változtatható állapot lefelé történő átadásához a hierarchiában.
Főbb pontok
@Binding egy Property Wrapper, amely kétirányú kapcsolatot hoz létre a szülőnézetben tárolt tulajdonság és a gyermekkomponens között. A Binding fő különbsége a @State-hez képest: a Binding nem birtokol adatokat. Csak olvassa és írja az értéket a valódi forráson — @State, @StateObject vagy más Binding a szülőben — keresztül. Binding nélkül a gyermeknézetek nem tudnák módosítani az ős állapotát callbackek vagy delegáltak nélkül.
A Binding egy struktúraként van implementálva két tulajdonsággal: wrappedValue (aktuális érték) és projectedValue (maga a Binding, $ segítségével érhető el). Amikor a gyermeknézet megváltoztatja a wrappedValue-t a Bindingen keresztül, a SwiftUI továbbítja a változást az adatforráshoz és újrarajzolja az összes függő nézetet. Ez szinkron módon történik az aktuális frissítési cikluson belül.
Fontos jellemző: a @Binding nem korlátozódik egyszintű átadásra. A Binding a hierarchia több szintjén keresztül is átadható — minden gyermekkomponens referenciát kap ugyanarra az adatforrásra. Bármely szinten történt változás az összes kapcsolódó nézet egységes frissítését okozza.
A kétirányú kapcsolat mechanizmusa a @Binding segítségével a Property Wrapperek projekciójára épül. Amikor a szülő @State var value: T deklarál, a SwiftUI automatikusan létrehozza a $value projekciót Binding
struct SliderContainer: View {
@State private var value: Double = 0.5
var body: some View {
VStack {
Text("Érték: \(value)")
SliderView(value: $value)
}
}
}
struct SliderView: View {
@Binding var value: Double
var body: some View {
Slider(value: $value, in: 0...1)
}
}
A példában a SliderContainer birtokolja a @State value-t, a SliderView pedig a $value-n keresztül kapja a Binding-et. A SliderView-en belüli csúszka ehhez a Binding-hez van kötve. A csúszka húzásakor a Slider megváltoztatja az értéket a Binding-en keresztül, ami automatikusan frissíti a @State-et a SliderContainer-ben, és mindkét nézet megjeleníti az aktuális számot. Az egész lánc egyetlen callback vagy értesítés nélkül működik.
A @StateObject vagy @ObservedObject alapján történő Binding létrehozásához ugyanaz a projekció használatos: $object.property Binding
A SwiftUI előtt a változások felfelé történő továbbításának szokásos módja a hierarchiában a callbackek és a delegáltak voltak: a szülő átadott egy closure-t, a gyermekkomponens meghívta azt változáskor. A @Binding alternatívát kínál kevesebb kóddal és deklaratívabb szintaxissal. A befejezési closure átadása helyett elég a $stateValue-t átadni.
| Szempont | @Binding | Callbackek |
|---|---|---|
| Kód | Egy annotáció + $ | Closure + hívás |
| Többszintűség | Automatikus | Closure lánc |
| Tesztelés | Binding(value:constant) | Mock-closure-ok |
| Olvashatóság | Magas | Közepes |
| Rugalmasság | Csak adatok | Bármilyen logika |
Használja a @Binding-et, amikor a gyermeknézetnek csak olvasnia és módosítania kell az értéket. Ha mellékhatásokra van szükség a változásnál (validáció, naplózás, hálózati kérés), kombinálja a Binding-et egy callback-kel: adja át a Binding-et az adatokhoz és a closure-t az eseményekhez. Például a TextField kötődhet a Binding-hez, az onChange pedig elindítja a validációt.
@Binding több tipikus forgatókönyvben alkalmazható. Az első — egyedi vezérlők: kapcsolók, csúszkák, színválasztók és más interaktív elemek Binding-et fogadnak a kétirányú szinkronizáláshoz. A második — modális ablakok: a sheet megjelenítési jelzője Binding-ként kerül átadásra, lehetővé téve a gyermeknézet számára, hogy bezárja magát a presentationMode vagy közvetlen beállítás segítségével.
A harmadik minta — felosztott űrlapok. Ha egy űrlap több mezőből áll, minden mező kivonható egy külön komponensbe, amely Binding-et fogad az értékéhez. Ez leegyszerűsíti a mezők tesztelését és újrafelhasználását a különböző űrlapok között. A szülőkomponens marad az egész űrlapmodell egyetlen tulajdonosa.
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)
}
}
}
A FormField komponens egy címkét és egy Binding-et fogad egy sztringhez. Megjelenít egy feliratot és egy TextField-et, amely az átadott Binding-hez van kötve. Bármely űrlap többször is használhatja a FormField-et a $property átadásával minden mezőhöz. Ez csökkenti a kódismétlést és központosítja a szövegmezők stílusát.
A SwiftUI lehetővé teszi a Binding manuális létrehozását a Binding(get:set:) inicializátoron keresztül. Ez akkor hasznos, ha logikát kell hozzáadni az érték olvasásához vagy írásához. Létrehozhat például egy Binding-et, amely formázza a számot mentés előtt, vagy egy Binding-et, amely minden változáskor szinkronizálja az értéket egy távoli szerverrel.
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)
}
}
A listában az egyedi emailBinding automatikusan kisbetűssé alakítja a szöveget és eltávolítja a szóközöket minden változáskor. A TextField ezt a Binding-et használja a $email-hez való közvetlen kötés helyett. Ez a megközelítés lehetővé teszi a validáció és az adatátalakítás központosítását a Binding-en belül, anélkül hogy a kódot onChange-kezelőkkel szennyezné.
Az első és leggyakoribb hiba — érték átadása Binding helyett. Ha egy gyermekkomponens @Binding var text: String-et deklarál, a szülő pedig text-et ad át ($ nélkül), a fordító hibát jelez: Cannot convert value of type 'String' to expected argument type 'Binding
Második hiba — Binding csak olvasható adatokra. Ha a gyermeknézetnek csak olvasnia kell az értéket, ne használjon @Binding-et — elég egy egyszerű let vagy @State a szülőből. A Binding írási lehetőséget feltételez, és a további módosítási jogosultságok megnehezítik a hibakeresést és megsértik a minimális jogosultság elvét.
Harmadik probléma — Binding.constant éles környezetben. A Binding.constant(value) hamis kötést hoz létre visszacsatolás nélkül — a változtatások figyelmen kívül maradnak. A constant-ot csak prototípuskészítéshez és előnézetekhez (Xcode Previews) használja, soha éles kódban. Tesztekhez használja a Binding(get:set:) vezérelt viselkedéssel.
Gyakran Ismételt Kérdések
@State birtokolja az adatokat és kezeli azok tárolását a kupacban. A @Binding csak hivatkozik a meglévő állapotra birtoklás nélkül. A @State mindig private, a @Binding — a gyermeknézet bemeneti paramétere.
Igen, a Binding(get:set:) inicializátoron vagy a Binding.constant(value) segítségével. A Binding @StateObject-ből is beszerezhető a $object.$property projekción keresztül, valamint Publisher-ből a Binding(get:set:) segítségével a Subscribe-on belül.
A @Binding láncban kerül átadásra: minden köztes komponens deklarál egy @Binding-et és továbbadja azt $-on keresztül. Minden szint ugyanarra az adatforrásra hivatkozik a gyökérnézetben.
A Binding.constant néma burkolót hoz létre — a setter figyelmen kívül hagyja az új értékeket. Csak prototípuskészítésre és SwiftUI Previews-ra tervezték, ahol nincs szükség visszacsatolásra a gyermekkomponenstől.
Igen, a Binding<T?> támogatott. Ha Binding<String?>-et ad át, a gyermeknézet nil-t állíthat be. Ez kényelmes opcionális űrlapmezőkhöz vagy visszaállítható állapotokhoz.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is