如何使用SwiftUI和Combine观察TextField值?

时间:2019-06-24 11:14:40

标签: ios swiftui combine

每次textField的值更改时,我都试图执行一个动作。

@Published var value: String = ""

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

但是我遇到了错误。

  

无法将“已发布”类型的值转换为预期参数类型“绑定”

4 个答案:

答案 0 :(得分:7)

在您的代码中,$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)
    }
}

答案 1 :(得分:3)

这应该是一种不脆弱的方法:

<ul>
    <li>
        <button id="left" onclick="page('prev','','')" class="disable">Prev</button>
    </li>
    <li id="page" onclick="page('','dots','')"></li>
    <li id="pagination"></li>
    <li>
        <button id="right" onclick="page('','','next')">Next</button>
    </li>
</ul>

答案 2 :(得分:2)

如果您想观察value,则应该为State

@State var value: String = ""

答案 3 :(得分:2)

我不使用合并。这对我有用:

 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