如何使用 SwiftUI 和 Combine 观察 TextField 值?
How to observe a TextField value with SwiftUI and Combine?
每次 textField
的值更改时,我都会尝试执行一个操作。
@Published var value: String = ""
var body: some View {
$value.sink { (val) in
print(val)
}
return TextField($value)
}
但是我得到以下错误。
Cannot convert value of type 'Published' to expected argument type 'Binding'
如果你想观察value
那么它应该是State
@State var value: String = ""
这应该是一种不脆弱的方式:
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)
}
}
我不为此使用组合。这对我有用:
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
在您的代码中,$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)
}
}
每次 textField
的值更改时,我都会尝试执行一个操作。
@Published var value: String = ""
var body: some View {
$value.sink { (val) in
print(val)
}
return TextField($value)
}
但是我得到以下错误。
Cannot convert value of type 'Published' to expected argument type 'Binding'
如果你想观察value
那么它应该是State
@State var value: String = ""
这应该是一种不脆弱的方式:
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)
}
}
我不为此使用组合。这对我有用:
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
在您的代码中,$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)
}
}