SwiftUI 5: 使用无属性包装器、State 和 Bindable 进行 @Observable object 更新

huangapple go评论62阅读模式
英文:

SwiftUI 5: @Observable object updates using no property wrappers, State and Bindable

问题

我有以下使用XCode 15 beta 4SwiftUI 5代码片段:

struct ContentView: View {
    var person: Person = .init(id: UUID(), name: "Stacey")
    //使用@State、@Bindable或在'person'之前不加任何修饰符都能完成相同的任务

    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
    }
}

我想知道在ContentView中在Person变量之前使用@Bindable@State或不使用修饰符的区别,因为使用这三种选择之一,person对象都可以成功更新,并且视图可以监听到新的更改。

英文:

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.

答案1

得分: 2

使用@Observable,您现在可以在体验中随处看到变化。

@Bindable用于进行更改,您可以使用$someObject.someProperty并更改对象的属性。

@State是真相之源,用于本地属性。

英文:

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.

答案2

得分: 0

这是因为您在类声明之前应用了@Observable,将您的类Person标记为ObservableObject。因此,您的实例person将始终观察更新,无论您在视图中提供的任何附加注释如何。

通常,当您想要跟踪非自定义类的变量(如布尔值、字符串、整数等)的次要更改时,您会使用@State@Bindable可以以类似的方式使用@State,只是更适用于将其应用于主视图中的自定义视图的初始化程序。请参考以下示例。

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 {
            // 做一些操作
         }
     }
}
英文:

> //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
         }
     }
}

huangapple
  • 本文由 发表于 2023年7月20日 15:02:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定