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 中通常没有用 View
s。
如果您想在初始化期间更新某种状态,请查看 this answer。
感谢 arsenius 解释为什么 属性 观察员在这种情况下没有开火。
作为修复,我删除了视图中的 属性,并将其替换为带有签名的初始化函数,其中包含要从 NavigationLink 调用传递的所需数据。在 init 中,我直接在 ViewModel 上调用了一个函数。
struct MyTestView: View {
@ObservedObject var vm = MyTestViewModel()
init(FSAC: String) {
if(FSAC != "") {
vm.SetFsac(FSAC: FSAC)
}
}
...
也设法解决了我的问题,我在视图中有一个切换但没有被触发。将用于切换的绑定变量移动到作为我的(视图)模型的观察对象,并从那里公开已发布的 属性。使用 Andy 和 arsenius 的信息。
我有一个带有附加 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 中通常没有用 View
s。
如果您想在初始化期间更新某种状态,请查看 this answer。
感谢 arsenius 解释为什么 属性 观察员在这种情况下没有开火。
作为修复,我删除了视图中的 属性,并将其替换为带有签名的初始化函数,其中包含要从 NavigationLink 调用传递的所需数据。在 init 中,我直接在 ViewModel 上调用了一个函数。
struct MyTestView: View {
@ObservedObject var vm = MyTestViewModel()
init(FSAC: String) {
if(FSAC != "") {
vm.SetFsac(FSAC: FSAC)
}
}
...
也设法解决了我的问题,我在视图中有一个切换但没有被触发。将用于切换的绑定变量移动到作为我的(视图)模型的观察对象,并从那里公开已发布的 属性。使用 Andy 和 arsenius 的信息。