Last active
October 5, 2022 09:12
-
-
Save zntfdr/9425d6e18e21eeeb352df0821207871e to your computer and use it in GitHub Desktop.
Revisions
-
zntfdr revised this gist
Jul 13, 2020 . 1 changed file with 15 additions and 15 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ // Original article here: https://www.fivestars.blog/code/swiftui-hierarchy-list.html import SwiftUI @@ -27,20 +27,6 @@ struct FileItem: Identifiable { ] } struct ContentView: View { let data: [FileItem] @@ -87,4 +73,18 @@ private struct RecursiveView<Data, RowContent>: View where Data: RandomAccessCol func containsSub(_ element: Data.Element) -> Bool { element[keyPath: children] != nil } } struct FSDisclosureGroup<Label, Content>: View where Label: View, Content: View { @State var isExpanded: Bool = false var content: () -> Content var label: () -> Label @ViewBuilder var body: some View { Button(action: { self.isExpanded.toggle() }, label: { label().foregroundColor(.blue) }) if isExpanded { content() } } } -
zntfdr created this gist
Jul 11, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,90 @@ import SwiftUI struct FileItem: Identifiable { let name: String var children: [FileItem]? var id: String { name } static let spmData: [FileItem] = [ FileItem(name: ".gitignore"), FileItem(name: "Package.swift"), FileItem(name: "README.md"), FileItem(name: "Sources", children: [ FileItem(name: "fivestars", children: [ FileItem(name: "main.swift") ]), ]), FileItem(name: "Tests", children: [ FileItem(name: "fivestarsTests", children: [ FileItem(name: "fivestarsTests.swift"), FileItem(name: "XCTestManifests.swift"), ]), FileItem(name: "LinuxMain.swift") ]) ] } struct FSDisclosureGroup<Label, Content>: View where Label: View, Content: View { @State var isExpanded: Bool = false var content: () -> Content var label: () -> Label @ViewBuilder var body: some View { Button(action: { self.isExpanded.toggle() }, label: { label().foregroundColor(.blue) }) if isExpanded { content() } } } struct ContentView: View { let data: [FileItem] var body: some View { // List(data, children: \.children, rowContent: { Text($0.name) }) HierarchyList(data: data, children: \.children, rowContent: { Text($0.name) }) } } public struct HierarchyList<Data, RowContent>: View where Data: RandomAccessCollection, Data.Element: Identifiable, RowContent: View { private let recursiveView: RecursiveView<Data, RowContent> public init(data: Data, children: KeyPath<Data.Element, Data?>, rowContent: @escaping (Data.Element) -> RowContent) { self.recursiveView = RecursiveView(data: data, children: children, rowContent: rowContent) } public var body: some View { List { recursiveView } } } private struct RecursiveView<Data, RowContent>: View where Data: RandomAccessCollection, Data.Element: Identifiable, RowContent: View { let data: Data let children: KeyPath<Data.Element, Data?> let rowContent: (Data.Element) -> RowContent var body: some View { ForEach(data) { child in if self.containsSub(child) { FSDisclosureGroup(content: { RecursiveView(data: child[keyPath: self.children]!, children: self.children, rowContent: self.rowContent) .padding(.leading) }, label: { self.rowContent(child) }) } else { self.rowContent(child) } } } func containsSub(_ element: Data.Element) -> Bool { element[keyPath: children] != nil } }