Please help me understand the difference between @Bindable and @State.
If I take the following example from the Xcode Documentation and change @Bindable with @State like this: @State var book: Book, it would work just fine.
@Observable
class Book: Identifiable {
var title = "Sample Book Title"
var isAvailable = true
}
struct BookEditView: View {
@Bindable var book: Book
@Environment(\.dismiss) private var dismiss
var body: some View {
Form {
TextField("Title", text: $book.title)
Toggle("Book is available", isOn: $book.isAvailable)
Button("Close") {
dismiss()
}
}
}
}
The same would apply to more complex examples as well.
So why should I ever consider using @Bindable if @State works the same way?
Before iOS 17, you would use
@Statefor value types (String,Int,Bool,struct,enum). If you needed to modify that state from a child view, you would use@Bindingand pass it as a parameter. If, instead of a value type you had a reference type (classconformingObservableObject), then you would use@StateObjectin the view that owned that model. In the child view that needed to modify that model, you would use@ObservedObject.With iOS 17 and the Observable protocol, there is some simplification to this.
@Stateis now used for both value types and reference types. Therefore, you use@Statein the view that you want to own the model. For child views, if you want to modify the state of an@Observableobject, you use@Bindable. For value types, you still use@Binding.If the child view does not need to modify the models, then you don't need to add any property wrapper.