Skip to content

Commit

Permalink
add all snippets from hierarchy list article
Browse files Browse the repository at this point in the history
  • Loading branch information
zntfdr committed Aug 15, 2021
1 parent aaaf1c1 commit 323bb83
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 0 deletions.
71 changes: 71 additions & 0 deletions Hierarchy-List/ContentView-1.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Original article here: https://www.fivestars.blog/code/swiftui-hierarchy-list.html

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 ContentView: View {
let data: [FileItem] = .spmData

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 let subChildren = child[keyPath: children] {
DisclosureGroup(content: {
RecursiveView(data: subChildren, children: children, rowContent: rowContent)
}, label: {
rowContent(child)
})
} else {
rowContent(child)
}
}
}
}
82 changes: 82 additions & 0 deletions Hierarchy-List/ContentView-2.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Original article here: https://www.fivestars.blog/code/swiftui-hierarchy-list.html

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 ContentView: View {
var data: [FileItem] = .spmData

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 let subChildren = child[keyPath: children] {
FSDisclosureGroup(content: {
RecursiveView(data: subChildren, children: children, rowContent: rowContent)
}, label: {
rowContent(child)
})
} else {
rowContent(child)
}
}
}
}

struct FSDisclosureGroup<Label, Content>: View where Label: View, Content: View {
@State var isExpanded: Bool = true
var content: () -> Content
var label: () -> Label

@ViewBuilder
var body: some View {
DisclosureGroup(isExpanded: $isExpanded, content: content, label: label)
}
}
File renamed without changes.

0 comments on commit 323bb83

Please sign in to comment.