【问题标题】:Do I have to use an ObservableObject in SwiftUI?我必须在 SwiftUI 中使用 ObservableObject 吗?
【发布时间】:2022-06-22 22:10:24
【问题描述】:

我想使用struct 而不是class 作为我的View 的状态,并且您可能知道,ObservableObject 是一个只有类才能遵守的协议。

我是否将我的结构包装在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))
    }
}

【问题讨论】:

  • 学习一些 SwiftUI 数据流教程。

标签: swift swiftui view viewmodel observableobject


【解决方案1】:

您不必使用@ObservedObject 来确保对模型对象的更新正在更新您的视图。

如果您想使用struct 作为模型对象,您可以使用@State,并且您的视图将在您的@State struct 更新时正确更新。

有很多不同的属性包装器,您可以在模型对象更新时使用它们来更新您的 SwiftUI 视图。您可以使用值类型和引用类型作为模型对象,但是,根据您的选择,您必须使用不同的属性包装器。

@State 只能用于值类型,@State 属性只能从视图本身内部更新(因此它们必须是 private)。

@ObservedObject(以及所有其他 ...Object 属性包装器,例如 @EnvironmentObject@StateObject)只能与符合 ObservableObject 的类一起使用。如果您希望能够从视图内部和外部更新模型对象,则必须使用具有适当属性包装器的 ObservableObject 一致类型,在这种情况下不能使用 @State

因此,请考虑可以从哪些来源更新您的模型对象(仅来自直接在您的 View 内或从视图外部捕获的用户输入 - 例如从其他视图或网络),无论您是否需要价值或参考语义,并相应地为您的数据模型做出适当的选择。

有关@ObservedObject@StateObject 之间差异的更多信息,请参阅What is the difference between ObservedObject and StateObject in SwiftUI

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    相关资源
    最近更新 更多