为什么在 SwiftUI 中的 TextField 绑定上调用 didSet 两次?

问题描述 投票:0回答:3

我有一个非常基本的视图,只显示一个

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
闭包两次? (我希望每个角色都会调用一次。)

代码有什么问题或者这是预期的行为吗? 🤔

swiftui binding textfield observableobject property-observer
3个回答
14
投票

我在 Xcode 14.2 RC 和 iOS 16.2 RC 上看到这个问题,但奇怪的是修复它的是添加

.textFieldStyle(.plain)
.textFieldStyle(.roundedBorder)

我真的不确定为什么没有 textFieldStyle 会影响这个,但是当我没有设置 textFieldStyle 时,绑定会调用 set:{} 两次,一旦我添加其中一个,它就会表现正常并且只调用 set :{} 一次一次。

我希望这对某人有帮助!


0
投票

有一个运算符

.removeDuplicates()
,您可以将其放在接收器之前,它将仅发布唯一值。
.textFieldStyle
的问题是,当文本字段失去焦点时,您仍然会收到额外的调用,或者至少在 macOS 上是这样。


-1
投票
 let binding = Binding<String>(get: {
                textvariable
            }, set: {
                viewModel.setText(query: $0) //add event inside setText
                // do whatever you want here
            })
© www.soinside.com 2019 - 2024. All rights reserved.