我有一个非常基本的视图,只显示一个
TextField
:
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
TextField("Enter a string...", text: $viewModel.string)
}
}
TextField
的文本绑定到视图模型上的string
属性:
class ViewModel: ObservableObject {
@Published var string: String = "" {
didSet {
print("didSet string:", string)
}
}
}
我添加了一个
didSet
属性观察器,以便在字符串更改时执行自定义操作。对于这个简单的例子,我只在控制台上打印一个字符串。
当我运行此代码并在文本字段中输入字符串“123”时,这是我得到的输出:
didSet string: 1
didSet string: 1
didSet string: 12
didSet string: 12
didSet string: 123
didSet string: 123
为什么?
为什么我输入的每个字符都会调用
didSet
闭包两次?
(我希望每个角色都会调用一次。)
代码有什么问题或者这是预期的行为吗? 🤔
我在 Xcode 14.2 RC 和 iOS 16.2 RC 上看到这个问题,但奇怪的是修复它的是添加
.textFieldStyle(.plain)
或 .textFieldStyle(.roundedBorder)
。
我真的不确定为什么没有 textFieldStyle 会影响这个,但是当我没有设置 textFieldStyle 时,绑定会调用 set:{} 两次,一旦我添加其中一个,它就会表现正常并且只调用 set :{} 一次一次。
我希望这对某人有帮助!
有一个运算符
.removeDuplicates()
,您可以将其放在接收器之前,它将仅发布唯一值。
.textFieldStyle
的问题是,当文本字段失去焦点时,您仍然会收到额外的调用,或者至少在 macOS 上是这样。
let binding = Binding<String>(get: {
textvariable
}, set: {
viewModel.setText(query: $0) //add event inside setText
// do whatever you want here
})