Binding vs Bindable vs State


Greetings, traveler!

Since we have discussed binding, let’s clarify Swift’s different options. iOS 17 and the new Observation framework gave us some new tools to consider, which widened our arsenal. So, let’s take a closer look at all of them once again.

State

Utilize the @State property wrapper to manage a single source of truth for a SwiftUI view. Working with Observable classes, you can mark their references as State objects. This will allow you to provide bindings to its properties.

struct SwiftUIView: View {
    
    @State var name: String = ""
    
    var body: some View {
        TextField("", text: $name)
    }
    
}

Binding

Use the @Binding property wrapper to establish a two-way connection between a property and a view. It connects a property to a source of truth stored at another object.

struct SwiftUIView: View {
    
    @State var name: String = ""
    
    var body: some View {        
        SwiftUIView2(name: $name)
    }
    
}

struct SwiftUIView2: View {
    
    @Binding var name: String
    
    var body: some View {
        TextField("", text: $name)
    }
    
}

Bindable

Utilize the @Bindable to create bindings to mutable properties of an Observable class. You can also use @Bindable to make bindings for an Environment object. You can read more about it here.

@Observable
final class Model {
    var name: String = ""
}

struct SwiftUIView: View {
    
    @State var model: Model
    
    var body: some View {
        SwiftUIView2(model: model)
    }
    
}

struct SwiftUIView2: View {
    
    @Bindable var model: Model
    
    var body: some View {
        TextField("", text: $model.name)
    }
    
}

Conclusion

The release of the Observation framework has decreased the number of property wrappers, which is good news.