为什么自定义绑定不更新 SwiftUI TextField?

时间:2021-07-01 17:51:10

标签: swift swiftui

我觉得我误解了 Binding 在 SwiftUI 中的工作方式,因为我不明白为什么当 {{1 }} 查看模型属性更改:

TextField

输入第一个 text 总是更新第二个(和 class MyViewModel: ObservableObject { @Published var text: String = "Hello" var binding: Binding<String>! init() { binding = Binding(get: { self.text }, set: { self.text = $0 }) } } struct MyView: View { @StateObject var viewModel = MyViewModel() var body: some View { VStack { Text("Actual: " + viewModel.text) TextField("Field 1", text: viewModel.binding) TextField("Field 2", text: $viewModel.text) } } } struct MyView_Previews: PreviewProvider { static var previews: some View { MyView() } } 标签),但输入第二个 TextField 只会将更改传播到 Text 标签,如图所示这里:

simulator screenshot

在我的实际用例中,TextField 视图列表是从用户定义的模板动态生成的,同样具有到 Text 复杂对象的自定义绑定(即不像 {{ 1}}) 在 TextField。以我有限的经验,我认为视图的动态特性使我无法以直接的方式对其进行编码,如第二个 @Published 所示。

我的猜测是 SwiftUI 不知道自定义绑定甚至应该需要刷新,在这种情况下,我的问题变成:如何告诉绑定“刷新”String 同时还支持动态-生成的内容?

1 个答案:

答案 0 :(得分:0)

首先考虑这行代码

binding = Binding(get: { self.text }, set: { self.text = $0 })

您正在通过 self.text 将绑定值分配给 self.text = $0,这意味着现在 self.text 值已更新,并且您的视图正在使用新值呈现,因此,它将以新值显示在所有地点。

现在,您正在通过第二个字段更改 @Published var 的值。当您更改此 var 时,您只是更改了 @Published var text: String 此 var 的值,并且与此绑定 var var binding: Binding<String>! 无关,没有通信或连接。所以 var binding: Binding<String>! 值不会改变,并保持与旧值相同。

如果要更新两个方向,还需要加上这个代码

@Published var text: String = "Hello" {
        didSet {
            binding = Binding(get: { self.text }, set: { self.text = $0 }) // <-- Here
        }
    }

所以现在它会在两面都有反映。


如果你还有困惑 替换这一行

var binding: Binding<String>!

有了这个

@Published var binding: String = ""

现在想想。上述方式与您的代码方式相同,只是有不同的声明。它们现在是两个不同的 var,但做同样的事情。