[英]Why does custom Binding not update SwiftUI TextField?
I feel like I'm misunderstanding how Binding
works in SwiftUI, in that I do not understand why the first TextField
below does not update when the text
view model property changes:我觉得我误解了 SwiftUI 中
Binding
工作原理,因为我不明白为什么当text
视图模型属性更改时下面的第一个TextField
不会更新:
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()
}
}
Typing in the first TextField
always updates second one (and the Text
label), but typing in the second TextField
only propagates changes to the Text
label, shown here:在第一个
TextField
键入总是更新第二个(和Text
标签),但在第二个TextField
键入只会将更改传播到Text
标签,如下所示:
In my actual use case, the list of TextField
views is dynamically generated from a user-defined template, likewise with custom bindings to a @Published
complex object (ie not as simple as a String
) on MyViewModel
.在我的实际使用的情况下,列表中
TextField
被动态地从一个用户定义的模板生成的视图,同样与自定义绑定至@Published
复杂对象(即,不作为简单如String
)上MyViewModel
。 In my limited experience, I believe the dynamic nature of the view prevents me from coding it in a straight-forward fashion, as seen with the second TextField
.以我有限的经验,我相信视图的动态特性阻止我以直接的方式对其进行编码,如第二个
TextField
所见。
My guess is that SwiftUI has no insight that the custom binding should even need to be refreshed, in which case my question becomes: How can I tell the binding to "refresh" the TextField
while also supporting dynamically-generated content?我的猜测是 SwiftUI 不知道自定义绑定甚至应该需要刷新,在这种情况下,我的问题变成:如何让绑定“刷新”
TextField
同时还支持动态生成的内容?
First, consider this line code首先,考虑这一行代码
binding = Binding(get: { self.text }, set: { self.text = $0 })
You are assigning binding value to self.text
by self.text = $0
, it means now self.text
value updated and your view is rendering with new value so, it will display with new value in the all place.您正在通过
self.text = $0
为self.text
分配绑定值,这意味着现在self.text
值已更新并且您的视图正在使用新值呈现,因此它将在所有位置以新值显示。
Now, you are changing the value of @Published
var by the second field.现在,您正在通过第二个字段更改
@Published
var 的值。 when you are changing this var, your just changing the value of @Published var text: String
this var and it's not related to this binding var var binding: Binding<String>!
当您更改此 var 时,您只需更改
@Published var text: String
this var 的值,它与此绑定 var var binding: Binding<String>!
无关var binding: Binding<String>!
there is no communication or connection.没有通信或连接。 so
var binding: Binding<String>!
所以
var binding: Binding<String>!
value is not changed and remains the same as the old value.值未更改并保持与旧值相同。
If you want to update both directions, you also need to add this code如果要更新两个方向,还需要添加这个代码
@Published var text: String = "Hello" {
didSet {
binding = Binding(get: { self.text }, set: { self.text = $0 }) // <-- Here
}
}
So now it will reflect on both sides.所以现在它会反映在双方。
If you have still confusion Replace this line如果您仍有困惑 更换此行
var binding: Binding<String>!
with this有了这个
@Published var binding: String = ""
And now think.现在想想。 The above way is the same way as your code, just have a different declaration.
上述方式与您的代码方式相同,只是有不同的声明。 These are now two different var but doing the same things.
这些现在是两个不同的 var 但做同样的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.