0

I have the following SwiftUI 5 code snippet using XCode 15 beta 4:

struct ContentView: View {
    var person: Person = .init(id: UUID(), name: "Stacey")
    //using @State or @Bindable or nothing before 'person' does the same job

    var body: some View {
        VStack {
            Button {
                person.name = "Sarah"
            } label: {
                Text("change name")
            }
            
            Text("Name: \(person.name)")
        }
    }
}

@Observable
class Person: Identifiable {
    var id: UUID
    var name: String
    
    init(id: UUID, name: String) {
        self.id = id
        self.name = name
    }
}

I wonder what is the difference between using: @Bindable, @State, or nothing before the Person variable in the ContentView, because the person object updates successfully using any of those 3 choices, and the view can listen to the new change.

JAHelia
  • 6,934
  • 17
  • 74
  • 134
  • 4
    [Discover Observation in SwiftUI](https://developer.apple.com/videos/play/wwdc2023/10149/), this is a good video from WWDC 2023 on the subject – Joakim Danielson Jul 20 '23 at 08:21

2 Answers2

2

With @Observable you can now see changes everywhere as you are experiencing.

@Bindable is to make changes , you can use $someObject.someProperty and change the property of the object.

@State is a source of truth it is for local properties.

lorem ipsum
  • 21,175
  • 5
  • 24
  • 48
  • we have now: `State`, `Binding`, `Bindable`, `StateObject`, `ObservedObject` wrappers, I just got confused between binding and bindable as both do the same result – JAHelia Jul 21 '23 at 12:55
  • 1
    @JAHelia StateObject and ObservedObject aren’t needed if you are only supporting iOS 17+ – lorem ipsum Jul 21 '23 at 13:10
0

//using @State or @Bindable or nothing before 'person' does the same job

This is because you marked your class Person as an ObservableObject via applying @Observable before the class declaration. Because of this, your instance, person will always observe updates regardless of any additional annotation you provide it in your view.

You typically use @State when you want to track minor changes to a variable of a non-custom class (like a boolean, string, integer, etc). @Bindable can be used in a similar fashion to @State except it is more useful to apply it to the initializer of a custom view within your primary view. See the following example.

struct PrimaryView: View {
     @State var updateCustomView: Bool = false

     var body: some View {
         CustomView(shouldUpdate: $updateCustomView)
     }
}

struct CustomView: View {
     @Bindable var shouldUpdate: Bool

     var body: some View {
         if shouldUpdate {
            // do stuff
         }
     }
}
Mary X
  • 153
  • 2
  • 15