Bindings in SwiftUI
Property wrappers were one of the recent additions to Swift. SwiftUI makes use of several very useful property wrappers. One of them is @Binding
. The @Binding
property wrapper is really just a convenience for the Binding<T>
type.
But before we go into using bindings, what are bindings?
Per Apple’s documentation, a binding connects a property to a source of truth stored elsewhere, instead of storing data directly. You would use a binding to create a two-way connection between a property that stores data, and a view that displays and changes the data.
In SwiftUI, you’ll find this to be a fairly common pattern, especially with built in input fields.
Binding Example
Let’s say we want a view with a switch for the user to interact with. How do we build it?
struct BindingExample: View {
@State var switchIsOn = false
var body: some View {
Form {
Toggle(isOn: $switchIsOn) {
Text("Switch 1")
}
}
}
}
First, we need a mutable variable to hold the state of our switch. In this case, we have a Bool
, named switchIsOn
. We have to use the @State
wrapper so it can be modified in our view.
Next, when we build our Toggle
, we need to provide a binding to a property that will hold the state of the toggle. When we pass in the variable, we use the dollar sign to denote that we’re binding to it. So our view holds the current state of switchIsOn
, while the Toggle
has a binding internally. When the state of the Toggle
flips, it is propagated through $switchIsOn
back into our view.
Creating a manual binding
If we again look at Apple’s description of a binding, we see that it involves a two-way connection. The binding needs to know the value to get, and where to set the new value when it is changed.
With that knowledge, we can look at how Binding
workings. Let’s look at our example again. This time, we’re going to make a binding ourselves.
struct BindingExample: View {
@State var switchIsOn = false
var body: some View {
Form {
Toggle(isOn: Binding(get: {
self.switchIsOn
}, set: { newValue in
self.switchIsOn = newValue
}) ) {
Text("Also Switch 1")
}
}
}
}
Binding
has an initializer that takes a couple of arguments. One, with the get
label, is a closure explaining where the binding gets its value. In our example, this is our switchIsOn
variable. The other, set
, is given the new value for the binding. This gives us the opportunity to do something with it now that it has changed. In our case, we’re setting switchIsOn
to the new value.
In its most basic form, Binding
opens up a lot of interesting possibilities. In later posts, I’ll talk about when we might want to create a binding between our views, as well as some interesting problems a manual binding can solve.
[…] my original post on Bindings in SwiftUI, I had mentioned when we might want to use a […]