【问题标题】:How to use Dictionary as @Binding var in SwiftUI如何在 SwiftUI 中使用 Dictionary 作为@Binding var
【发布时间】:2020-07-10 19:11:25
【问题描述】:

我需要在 SwiftUI 中显示一个折叠菜单,可以将一个布尔值作为绑定 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...")
            }
        }

}

在子菜单行中:

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
            }
        }
    }
}

如果我只使用一个布尔值作为绑定变量,则代码运行正常,但是,如果我想使用字典来存储数组的每个状态,则会出现其他错误,请参阅图像吹:

如果我使用上面的行,那很好。

知道如何解决它吗?

谢谢

【问题讨论】:

  • Dictionary 不是 RandomAccessCollection,因此在 ForEach 和 Binding 中不受支持,请使用包含 title 和 selected(据我了解)属性的 MenuItem 结构数组的视图模型。不要撞墙——换个思路。 =)
  • 可以创建可绑定字典stackoverflow.com/questions/56978746/…

标签: binding swiftui


【解决方案1】:

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

正如 Asperi 所述,ForEach 要求数据源符合 RandomAccessCollection。 此要求不适用于 State 属性包装器!

让我们在下一个sn-p(复制-粘贴-运行)中看看其中一种可能的方法

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()
    }
}

结果如下

【讨论】:

    猜你喜欢
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    相关资源
    最近更新 更多