ios - SwiftUI 在 Bindable 属性更改时运行方法调用
问题描述
我正在努力理解如何在 Bindable 对象更改时运行方法。这是我到目前为止的代码:
但是,由于某种原因,由于 searchText 的变化,fetchFoods 方法永远不会被调用,我似乎无法理解为什么。
解决方案
@Harish @Asperi 你在这里搞糊涂了。@Harish 的方法没有被调用是有特定原因的。让我们创建一个简单的示例:
struct ContentView: View {
@State private var text = "" {
didSet {
print("Triggered!")
}
}
var body: some View {
VStack {
TextField("Type something...", text: $text)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
如果您复制粘贴并运行这个最小可行示例,您将看到字符串“已触发!” 永远不会被打印出来。这是因为您通过 $ 绑定更改的不是text
属性,而是通过符号访问的绑定包装值。$
它们是两种完全不同的东西。理解这一点非常重要。
那么,为什么@Asperi 的示例有效?(我稍微简化了它以创建另一个最小可行示例):
struct ContentView: View {
@State private var isOn = false {
didSet {
print("Triggered!")
}
}
var body: some View {
Button(
action: { self.isOn.toggle() },
label: { Text(self.isOn ? "Hide" : "Show") }
)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
这一次,如果您复制粘贴此代码,您将看到“已触发!” 将被打印。这很好,因为点击您正在更改的按钮self.isOn
。这次您没有使用任何$
符号来访问绑定包装的值。
上面的示例似乎使用了相同的方法,但实际上它们确实不同。同样,了解这种差异非常重要。那么,您如何才能得到您想要的(即“在 Bindable 对象更改时运行方法”)?您必须依赖 aViewModel
和@Published
属性包装器:
class ViewModel: ObservableObject {
@Published var text = "" {
didSet {
print("Triggered!")
}
}
}
struct ContentView: View {
@ObservedObject var viewModel = ViewModel()
var body: some View {
VStack {
TextField("Type something...", text: $viewModel.text)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
这正是为此目的:
Combine 的 Published 属性包装器在精神上类似于 [与其他属性包装器],允许客户端订阅 @Published 属性(通过 $ 投影) 以在值更改时接收更新。
来自https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md
推荐阅读
- python - 重塑图像实际上有什么作用?
- webfocus - 有谁知道我在哪里可以找到有关 WebFOCUS 的培训?
- c++ - 使用较大数组的一部分调用函数
- drupal-8 - 如何从作为对分类术语的实体引用的多选字段中获取值
- php - 跨域请求仅支持协议方案,我该怎么办?
- python - 使用 beautifulsoup 从“td”标签中解析整数
- drupal - 如何连接代码以更改 Drupal 模块行为?
- python-3.x - 在 Seaborn 中:ValueError:2583019x1677798 像素的图像尺寸太大。每个方向必须小于 2^16
- javascript - 迭代与递归的大 O 区别是什么?
- ios - How can I detect programmatically (egIBAction) when the tab selection changes views?