swiftui - 如何将 SwiftUI 元素绑定到字典中的值?
问题描述
我有一本字典,其中包含我想要“过滤”的各种值。所以我正在做这样的事情
struct ExampleView : View {
@EnvironmentObject var externalData : ExternalData
var body: some View {
VStack {
ForEach(externalData.filters) { (v : (String, Bool)) in
Toggle(isOn: $externalData.filters[v.0], label: {
Text("\(v.0)")
})
}
}
}
}
final class ExternalData : BindableObject {
let didChange = PassthroughSubject<ExternalData, Never>()
init() {
filters["Juniper"] = true
filters["Beans"] = false
}
var filters : Dictionary<String, Bool> = [:] {
didSet {
didChange.send(self)
}
}
}
这个问题似乎相关,但放置动态似乎没有帮助,我无法弄清楚在这种情况下如何做 NSObject 继承的事情。现在,这段代码给了我这个错误:
Cannot subscript a value of type 'Binding<[String : Bool]>' with an argument of type 'String'
但是尝试移动 $ 或以各种方式使用 paren 似乎无济于事。如何将切换绑定到字典中的值?我可以为每个值进行手动切换,但这会使代码变得脆弱,因为(除其他原因外)潜在的过滤器值基于可能在某些时候具有新值的数据集。
我知道在迭代它们之前我真的应该(以某种方式)对键进行排序,以便排序是一致的,但这会使这个例子变得混乱,所以我把那个代码省略了。
解决方案
我设法通过为每个过滤器使用自定义绑定来完成工作。
final class ExternalData: BindableObject {
let didChange = PassthroughSubject<Void, Never>()
var filters: Dictionary<String, Bool> = [:] {
didSet {
didChange.send(())
}
}
init() {
filters["Juniper"] = true
filters["Beans"] = false
}
var keys: [String] {
return Array(filters.keys)
}
func binding(for key: String) -> Binding<Bool> {
return Binding(getValue: {
return self.filters[key] ?? false
}, setValue: {
self.filters[key] = $0
})
}
}
该keys
属性列出了filters
键,String
以便可以显示(使用ForEach(externalData.keys)
)
该binding(for:)
方法为给定的键创建自定义Binding
。这个绑定被赋予Toggle
读/写包装字典中的当前值。
视图代码:
struct ExampleView : View {
@EnvironmentObject var externalData : ExternalData
var body: some View {
VStack {
ForEach(externalData.keys) { key in
Toggle(isOn: self.externalData.binding(for: key)) {
Text(key)
}
}
}
}
}
推荐阅读
- google-bigquery - 在 Bigquery 中使用“计划查询”时如何避免重复数据
- ruby-on-rails - 将粉碎合并到现有的 Rails 应用程序中
- angular - 如何检测 Angular 7 中的 url 变化包括参数和查询参数
- php - PHP HTML表格设置在x列之后的列旁边
- wordpress - 插件和 Wordpress.com 功能使用相同的简码
- python - 为什么字典比python中设置的时间少?
- java - 通过 Bean Validation API 中的自定义消息管理异常
- java - 如何将引用指针更改为另一个对象
- php - 什么类型的项目节点可以用js代替php
- reactjs - 无论如何将javascript控制台日志推送到哨兵