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

Mis*_*cha 25 binding textfield property-observer swiftui observableobject

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

看法

struct ContentView: View {

    @StateObject var viewModel = ViewModel()
    
    var body: some View {
        TextField("Enter a string...", text: $viewModel.string)
    }
    
}
Run Code Online (Sandbox Code Playgroud)

TextField文本绑定到string视图模型上的属性:

视图模型

class ViewModel: ObservableObject {
    
    @Published var string: String = "" {
        didSet {
            print("didSet string:", string)
        }
    }
    
}
Run Code Online (Sandbox Code Playgroud)

我添加了一个didSet属性观察器,以便在字符串更改时执行自定义操作。对于这个简单的例子,我只在控制台上打印一个字符串。

观察

当我运行此代码并在文本字段中输入字符串“123”时,这是我得到的输出:

didSet string: 1
didSet string: 1
didSet string: 12
didSet string: 12
didSet string: 123
didSet string: 123
Run Code Online (Sandbox Code Playgroud)

问题:

为什么?
为什么didSet我输入的每个字符都会调用两次闭包?(我希望每个角色都会调用一次。)

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

sah*_*ziz 16

我\xe2\x80\x99m 在 Xcode 14.2 RC 和 iOS 16.2 RC 上看到这个问题,但奇怪的是修复它的是添加一个.textFieldStyle(.plain).textFieldStyle(.roundedBorder)

\n

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

\n

我希望这可以帮助别人!

\n

  • 哇。如果不是那么荒谬的话,这会很有趣。 (2认同)

الع*_*عبد -1

 let binding = Binding<String>(get: {
                textvariable
            }, set: {
                viewModel.setText(query: $0) //add event inside setText
                // do whatever you want here
            })
Run Code Online (Sandbox Code Playgroud)