Как использовать словарь как @Binding var в SwiftUI - PullRequest
0 голосов
/ 30 марта 2020

Мне нужно будет отобразить свернутое меню в 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...")
            }
        }

}

в ChildMenu Row:

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

Если я использую только один единственный bool в качестве привязки var, код работает нормально, однако, если я хотел бы использовать словарь для хранения каждого состояния массива, в нем есть ошибка чего-то другого, см. изображение удара: enter image description here

если я использую строку выше, это нормально.

Есть идеи, как это исправить?

Спасибо

1 Ответ

1 голос
/ 30 марта 2020

Как использовать словарь в качестве хранилища изменяемых значений с оболочкой свойства State?

Как упоминалось в Asperi, ForEach требует, чтобы источник данных соответствовал RandomAccessCollection. Это требование не относится к оболочке свойства State!

Давайте рассмотрим один из возможных подходов в следующем фрагменте (копировать - вставить - запустить)

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

со следующим результатом

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...