【问题标题】:How to observe a TextField value with SwiftUI and Combine?如何使用 SwiftUI 观察 TextField 值并结合?
【发布时间】:2019-11-06 04:34:16
【问题描述】:

每当textField 的值发生更改时,我都会尝试执行一个操作。

@Published var value: String = ""

var body: some View {            
     $value.sink { (val) in
        print(val)
     }
     return TextField($value)       
}

但我得到以下错误。

无法将“Published”类型的值转换为预期的参数类型“Binding”

【问题讨论】:

    标签: ios swiftui combine


    【解决方案1】:

    如果你想观察value那么它应该是State

    @State var value: String = ""
    

    【讨论】:

    • 我也尝试将 didSet 用于 State var,但没有成功
    • 你为什么要尝试点集?删除 $value.sink { (val) in print(val) } 并留下一个打印,它会工作
    • $value 包含整个文本字段值,而 $value.publisher().sink { } 让您在每次击键时执行一些操作。检查我发布的答案。
    • 不适合我,因为我认为 $value.publisher().sink { } 在 Beta 6 中已被弃用。您有任何其他解决方案如何观察 TextField 值
    • @Evana 它还在,只需致电 value.publisher.sink { }
    【解决方案2】:

    这应该是一种非脆弱的方式:

    class MyData: ObservableObject {
        var value: String = "" {
            willSet(newValue) {
                print(newValue)
            }
        }
    }
    
    struct ContentView: View {
        @ObservedObject var data = MyData()
        var body: some View {
            TextField("Input:", text: $data.value)
        }
    }
    

    【讨论】:

      【解决方案3】:

      我不为此使用组合。这对我有用:

       TextField("write your answer here...",
                  text: Binding(
                           get: {
                              return self.query
                             },
                           set: { (newValue) in
                              self.fetch(query: newValue) // any action you need
                                      return self.query = newValue
                            }
                  )
        )
      

      我不得不说这不是我的主意,我在这个博客中看到它:SwiftUI binding: A very simple trick

      【讨论】:

      • 不是最好的选择,Combine 更容易。
      • @evya,你能解释一下吗?我更喜欢使用 Combine!
      【解决方案4】:

      在您的代码中,$value 是发布者,而 TextField 需要绑定。虽然您可以从@Published 更改为@State 甚至@Binding,但在值更改时无法观察到事件。

      似乎没有办法观察绑定。

      另一种方法是使用 ObservableObject 包装您的值类型,然后观察发布者 ($value)。

      class MyValue: ObservableObject {
        @Published var value: String = ""
        init() {
          $value.sink { ... }
        }
      }
      

      那么在你看来,你有绑定$viewModel.value

      struct ContentView: View {
          @ObservedObject var viewModel = MyValue()
          var body: some View {
              TextField($viewModel.value)
          }
      }
      

      【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-10
      • 2020-07-29
      相关资源
      最近更新 更多