how to make the code simpler and more reusable for navigation links with multi dimension dictionary in swiftui?

后端 未结 2 1895
旧时难觅i
旧时难觅i 2021-01-28 03:35

I have a multi-level dictionary that I need use to build navigation links. Now I have a 2-level depth dictionary:

let multiDimDict: [String: [[String: [String]]]         


        
2条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-28 03:46

    It is not clear from provided snapshot how list of dictionaries should be presented, and, actually, why is it used a dictionary as base model at all, but irrelative to uncertainties here is possible direction (not final but tested & can be considered)

    struct PlayingWithMultiDimNavLink2: View {
    
        let multiDimDict: [String: [[String: [String]]]]
        = ["A": [["A1": ["A11", "A12"]], ["A2": ["A21", "A22"]]],
           "B": [["B1": ["B11", "B12"]], ["B2": ["B21", "B22"]]]
            ]
    
        var body: some View {
           NavigationView{
                GenericChildView(model: multiDimDict)
            }
        }
    }
    
    struct GenericChildView: View {
        let model: [String: Any]
    
        var body: some View {
            List{
                ForEach(model.keys.sorted(), id: \.self) { key in
                    self.nextLevelView(for: key)
                }
            }
        }
    
        private func nextLevelView(for key: String) -> some View {
            let next = model[key]
            return Group {
                if next as? String != nil {
                    Text(next as! String)
                } else if next as? [Any] != nil {
                    NavigationLink(destination: GenerateChildListView(infoList: next as! [Any]))
                        { Text(key) }
                } else if next as? [String: Any] != nil {
                    NavigationLink(destination: GenericChildView(model: next as! [String: Any]))
                        { Text(key) }
                }
            }
        }
    }
    
    struct GenerateChildListView: View {
    
        var infoList: [Any]
    
        init(infoList: [Any]){
            self.infoList = infoList
        }
    
        var body: some View {
            Group {
                if infoList.count == 1 {
                    self.singleContentView()
                }
                if infoList.count > 1 {
                    List{
                        self.contentView()
                    }
                }
            }
        }
    
        private func singleContentView() -> some View {
            return Group {
                if infoList as? [String] != nil {
                    Text(infoList[0] as! String)
                } else if infoList as? [[String: Any]] != nil {
                    GenericChildView(model: self.infoList[0] as! [String: Any])
                }
            }
        }
    
        private func contentView() -> some View {
            return Group {
                if infoList as? [String] != nil {
                    ForEach(infoList as! [String], id:\.self) { content in
                        Text(content)
                    }
                } else if infoList as? [[String: Any]] != nil {
                    ForEach((infoList as! [[String: Any]]).indices, id: \.self) { i in
                        GenericChildView(model: self.infoList[i] as! [String: Any])
                    }
                }
            }
        }
    }
    

提交回复
热议问题