我想使用 struct
而不是 class
作为我的 View
的状态,正如您可能知道的,ObservableObject
是一个只有类才能遵守的协议(protocol)。
我是否必须将我的结构包装在 ViewModel
或其他类似类型的对象中?如果我不这样做会怎样?
现在的示例:
import Foundation
import SwiftUI
struct Object3D {
var x : Int
var y : Int
var z : Int
var visible : Bool
}
struct NumberView<Number : Strideable> : View {
var label : String
@State var number : Number
var body : some View {
HStack {
TextField(
self.label,
value: self.$number,
formatter: NumberFormatter()
)
Stepper("", value: self.$number)
.labelsHidden()
}
}
}
struct ObjectInspector : View {
@State var object : Object3D
var body : some View {
VStack {
Form {
Toggle("Visible", isOn: $object.visible)
}
Divider()
Form {
HStack {
NumberView(label: "X:", number: object.x)
NumberView(label: "Y:", number: object.y)
NumberView(label: "Z:", number: object.z)
}
}
}
.padding()
}
}
struct ObjectInspector_Previews: PreviewProvider {
static var previews: some View {
ObjectInspector(object: Object3D(x: 0, y: 0, z: 0, visible: true))
}
}
最佳答案
您不必使用@ObservedObject
来确保对模型对象的更新正在更新您的 View 。
如果您想使用struct
作为模型对象,则可以使用@State
,并且每当您的@State
时,您的 View 都会正确更新code> struct
已更新。
每当更新模型对象时,您都可以使用许多不同的属性包装器来更新 SwiftUI View 。您可以使用值类型和引用类型作为模型对象,但是,根据您的选择,您必须使用不同的属性包装器。
@State
只能用于值类型,并且 @State
属性只能从 View 本身内部更新(因此它们必须是private
).
@ObservedObject
(以及所有其他 ...Object 属性包装器,例如 @EnvironmentObject
和 @StateObject
)只能与符合 ObservableObject
的类。如果您希望能够从 View 内部和外部更新模型对象,则必须使用具有适当属性包装器的 ObservableObject
一致类型,不能使用 @State
在这种情况下。
因此,请考虑可以从哪些来源更新模型对象(仅从直接在 View
内部捕获的用户输入或从 View 外部捕获的用户输入 - 例如从其他 View 或从网络) ,无论您需要值语义还是引用语义,并相应地为您的数据模型做出适当的选择。
有关 @ObservedObject
和 @StateObject
之间差异的更多信息,请参阅 What is the difference between ObservedObject and StateObject in SwiftUI .
关于swift - 我必须在 SwiftUI 中使用 ObservableObject 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72716844/