我有一个词典,其中包含我要“过滤”的各种值。所以我正在做这样的事情
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)
}
}
}
This question似乎相关,但是动态设置似乎无济于事,在这种情况下,我无法弄清楚该如何执行NSObject继承。现在,此代码按原样显示此错误:
Cannot subscript a value of type 'Binding<[String : Bool]>' with an argument of type 'String'
但是尝试以各种方式移动$或使用paren似乎无济于事。如何将切换开关绑定到字典中的值?我只能为每个值进行手动切换,但这会使代码变得脆弱,因为(除其他原因外)潜在的过滤器值基于某个数据集,该数据集有时可能具有新值。
我知道我应该先对键进行排序(以某种方式),然后再遍历它们,以便顺序一致,但这使该示例混乱,因此我省略了该代码。
答案 0 :(得分:2)
我设法通过对每个过滤器使用自定义绑定来使之工作。
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)
}
}
}
}
}