【问题标题】:Why is didSet called twice on the TextField binding in SwiftUI?为什么在 SwiftUI 中的 TextField 绑定上调用了两次 didSet?
【发布时间】:2022-06-28 17:21:46
【问题描述】:

我有一个非常基本的视图,只显示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 1 或 2 中,根本没有调用它。如果您有敏感的副作用,请尝试使用属性发布者/组合。
  • 有趣。使用财产发布者是什么意思?通过$string.sink {...}收听变化?
  • 我遇到了同样的问题,我不知道为什么会这样。我知道 didSet + 属性包装器在 Swift 中表现得很奇怪。也许这是一个错误? forums.swift.org/t/…
  • 我也有同样的问题。即使使用 combine .. .$string.sink {...} 值也会到达两次。
  • 我也遇到了这个问题,在我的情况下,每当输入新字符时,文本字段也会查询我的数据库(以自动完成输入),因此我进行了两次必要的调用。有没有人向苹果开过票,或者在 swift 论坛上发过关于这个的帖子?

标签: swiftui binding textfield observableobject property-observer


【解决方案1】:
 let binding = Binding<String>(get: {
                textvariable
            }, set: {
                viewModel.setText(query: $0) //add event inside setText
                // do whatever you want here
            })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 2019-10-02
    相关资源
    最近更新 更多