What is SwiftUI @Binding?
@Binding is a crucial property wrapper that allows you to create a two-way connection between a value stored in one view and a property in another view.
Why do we need @Binding?
SwiftUI views are generally designed to be lightweight and to derive their content from their state.
When a view needs to pass data down to a child view, and that child view needs to be able to modify that data and have the parent view react to those changes, @Binding comes into play.
The problem without @Binding:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | struct ParentView: View { @State private var counter = 0 // Source of truth var body: some View { VStack { Text("Parent Counter: \(counter)") ChildView(value: counter) // Passing 'counter' by value (a copy) } } } struct ChildView: View { var value: Int // Receives a copy of the counter var body: some View { Button("Increment in Child") { // value += 1 // ERROR: Cannot assign to property: 'value' is a 'let' constant (or even if it's a var, it's a copy!) } } } | cs |
In this scenario, ChildView receives a copy of counter. Even if you make value a var, modifying it within ChildView would only change that local copy, and the ParentView's counter would remain unchanged.
How @Binding solves this:
@Binding allows the child view to directly manipulate the parent's @State
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import SwiftUI struct ParentView: View { @State private var counter = 0 // This is the single source of truth var body: some View { VStack { Text("Parent Counter: \(counter)") // Pass a binding to the child using '$' ChildView(value: $counter) } } } struct ChildView: View { @Binding var value: Int // Declared as a @Binding, receives a reference var body: some View { Button("Increment in Child") { value += 1 // This now directly modifies the 'counter' in ParentView! } } } | cs |
If value is modified in ChildView, counter in ParentView is immediately updated, and any view that depends on counter will re-render.
If counter is modified in ParentView, value in ChildView is also immediately updated, and ChildView will re-render if it depends on value.
++) @Binding vs @State vs @ObservedObject / @StateObject
- @State: Owns a simple value type (structs, enums, basic types like Int, String, Bool).
It's the source of truth for local view state.
- @ObservedObject / @StateObject: Owns a reference type (class conforming to ObservableObject).
It's the source of truth for complex object models. (@StateObject for ownership, @ObservedObject for observing already-owned objects).
- @Binding: Does not own data. It provides a two-way connection to a source of truth owned elsewhere. It's how child views manipulate data owned by their parents.
0 댓글