如何在 SwiftUI 中使用字典作为 @Binding var

mat*_*tee 2 binding swiftui

我需要在 SwiftUI 中显示折叠菜单,可以将一个 bool 值作为绑定 var 传递到子视图,但在尝试从字典传递该值时陷入困境。

参见下面的代码:

struct MenuView: View {
    @EnvironmentObject var data: APIData
    @State var menuCollapsed:[String: Bool] = [:]
    @State var isMenuCollapsed = false;

// I am able to pass self.$isMenuCollapsed but self.$menuCollapsed[menuItem.name], why?

var body: some View {

            if data.isMenuSynced {
                List() {
                    ForEach((data.menuList?.content)!, id: \.name) { menuItem in
                        TopMenuRow(dataSource: menuItem, isCollapsed: self.$isMenuCollapsed)
                            .onTapGesture {
                                if menuItem.isExtendable() {
                                    let isCollapsed = self.menuCollapsed[menuItem.name]
                                    self.menuCollapsed.updateValue(!(isCollapsed ?? false), forKey: menuItem.name)
                                } else {
                                    print("Go to link:\(menuItem.url)")
                                }

                            }
                    }
                }
            }else {
                Text("Loading...")
            }
        }

}
Run Code Online (Sandbox Code Playgroud)

在子菜单行中:

struct TopMenuRow: View {
    var dataSource: MenuItemData
    @Binding var isCollapsed: Bool

    var body: some View {
        ChildView(menuItemData)
            if self.isCollapsed {
                //display List of child data etc
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我只使用一个 bool 作为绑定变量,代码运行正常,但是,如果我想使用字典来存储数组的每个状态,它就会出现其他错误,请参见下图: 在此输入图像描述

如果我使用上面的行,那就没问题了。

知道如何修复它吗?

谢谢

use*_*734 7

如何使用字典作为状态属性包装器的可变值的存储?

正如 Asperi 提到的,ForEach 要求数据源符合 RandomAccessCollection。此要求不适用于 State propertywrapper!

让我们看看下一个片段中可能的方法之一(复制 - 粘贴 - 运行)

import SwiftUI

struct ContentView: View {

    @State var dict = ["alfa":false, "beta":true, "gamma":false]

    var body: some View {
        List {
            ForEach(Array(dict.keys), id: \.self) { (key) in
                HStack {
                    Text(key)
                    Spacer()
                    Text(self.dict[key]?.description ?? "false").onTapGesture {
                        let v = self.dict[key] ?? false
                        self.dict[key] = !v
                    }.foregroundColor(self.dict[key] ?? false ? Color.red: Color.green)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

结果如下

在此输入图像描述