SwiftUI View 属性 willSet & didSet 属性 观察者不工作

SwiftUI View Property willSet & didSet property observers not working

我有一个带有附加 ViewModel 的 SwiftUI (Beta 5) 视图。我想通过 navigationLink 导航到它并传入一个简单的参数(在这种情况下称为 FSAC)

我使用

导航
NavigationLink("Next", destination: MyTestView(FSAC: "testFsac"))

视图有一个 FSAC 属性 with willSet 和 didSet 属性 observer

struct MyTestView: View {
    @ObservedObject var vm = MyTestViewModel()

var FSAC: String {
    willSet {
        print("will set fsac")
    }
    didSet {
        print("did set fsac")
        vm.FSAC = FSAC
    }
}

var body: some View {
    VStack {
        Text("FSAC: \(FSAC)")
        Text("VM FSAC: \(vm.FSAC)")
    }
}

}

从未调用打印语句。第一个文本框正确显示参数;第二个是空白。

如何让 属性 观察者开火?

更一般地说,是否有 "correct" 方法使用 navigationLink 将参数传递给具有 ViewModel 的视图?

编辑: iOS 14 属性 观察者的工作方式与 iOS 13 相同。但是,我们现在有 .onChange(of:perform:) 作为替代。 Docs

Text(self.myString).onChange(of: self.myString) { newValue in print("myString changed to: \(newValue)") }

属性 基本 var 的观察者技术上 在 SwiftUI 中工作。如果你做类似 var view = MyTestView(...) 然后 view.FSAC = "updated" 的观察者将会开火(我已经验证了这一点)。

但是,通常使用 SwiftUI,您 构造 View(这是 struct 而不是 class ) 在每个布局过程中 body 内。在你的情况下 var body: some View { MyTestView(FSAC: "FSAC Value") }.

属性 观察者不会在初始化期间触发,因此它们在 SwiftUI 中通常没有用 Views。

如果您想在初始化期间更新某种状态,请查看 this answer

感谢 arsenius 解释为什么 属性 观察员在这种情况下没有开火。

作为修复,我删除了视图中的 属性,并将其替换为带有签名的初始化函数,其中包含要从 NavigationLink 调用传递的所需数据。在 init 中,我直接在 ViewModel 上调用了一个函数。

struct MyTestView: View {

    @ObservedObject var vm = MyTestViewModel()

    init(FSAC: String) {
        if(FSAC != "") {
            vm.SetFsac(FSAC: FSAC)
        }
    }
...

也设法解决了我的问题,我在视图中有一个切换但没有被触发。将用于切换的绑定变量移动到作为我的(视图)模型的观察对象,并从那里公开已发布的 属性。使用 Andy 和 arsenius 的信息。