Made my own version of DisclosureGroup since Apple's version can be a bit crashy.

This commit is contained in:
Casey Fleser 2022-07-30 09:29:04 -05:00
parent e75373084a
commit e642dbe25b
4 changed files with 53 additions and 22 deletions

View file

@ -17,7 +17,7 @@ struct ContentView: View {
var body: some View {
VStack {
NavigationView {
List {
List(selection: $state.selection) {
Divider()
switch state.base {
@ -26,12 +26,12 @@ struct ContentView: View {
case let .device(_, item):
ForEach(item.visibleChildren) {
SourceItemGroup(selection: $state.selection, item: $0)
SourceItemGroup(item: $0, selection: $state.selection)
}
case let .runtime(_, item):
ForEach(item.visibleChildren) {
SourceItemGroup(selection: $state.selection, item: $0)
SourceItemGroup(item: $0, selection: $state.selection)
}
}
}

View file

@ -16,6 +16,7 @@ protocol SourceItem: Identifiable, ObservableObject {
var children : [Child] { get set }
var visibleChildren : [Child] { get set }
var customImgDesc : SourceImageDesc? { get }
var isExpanded : Bool { get set }
}
extension SourceItem {
@ -54,10 +55,21 @@ extension SourceItem {
return match || !visibleChildren.isEmpty
}
func toggleExpanded(_ expanded: Bool? = nil, deep: Bool) {
isExpanded = expanded ?? !isExpanded
if deep {
for child in children {
child.toggleExpanded(isExpanded, deep: true)
}
}
}
}
class SourceItemVal<Model: SourceItemData, Child: SourceItem>: SourceItem {
@Published var visibleChildren : [Child]
@Published var isExpanded : Bool
var id = UUID()
var data : Model
@ -70,6 +82,7 @@ class SourceItemVal<Model: SourceItemData, Child: SourceItem>: SourceItem {
self.children = children
self.visibleChildren = children
self.customImgDesc = customImgDesc
self.isExpanded = false
}
}
@ -78,4 +91,5 @@ class SourceItemNone: SourceItem {
var data = SourceItemDataNone()
var children = [SourceItemNone]()
var visibleChildren = [SourceItemNone]()
var isExpanded = false
}

View file

@ -8,25 +8,41 @@
import SwiftUI
struct SourceItemGroup<Item: SourceItem>: View {
@State private var isExpanded = false // would like to move into Item
@Binding var selection: UUID?
@StateObject var item: Item
@StateObject var item : Item
@Binding var selection : UUID?
var body: some View {
if item.visibleChildren.count > 0 {
DisclosureGroup(
isExpanded: $isExpanded) {
ForEach(item.visibleChildren) { childItem in
SourceItemGroup<Item.Child>(selection: $selection, item: childItem)
}
} label: {
SourceItemLink(selection: $selection, item: item)
}
HStack(spacing: 0) {
let button = Button(action: {
let optionActive = NSApplication.shared.currentEvent?.modifierFlags.contains(.option) == true
}
else {
withAnimation(.easeInOut(duration: 0.2)) {
item.toggleExpanded(deep: optionActive)
}
}, label: {
Image(systemName: "chevron.right")
.padding(.horizontal, 2.0)
.contentShape(Rectangle())
.rotationEffect(.degrees(item.isExpanded ? 90.0 : 0.0))
})
.buttonStyle(.plain)
if item.visibleChildren.count == 0 {
button.hidden()
}
else {
button
}
SourceItemLink(selection: $selection, item: item)
}
if item.isExpanded {
ForEach(item.visibleChildren) { childItem in
SourceItemGroup<Item.Child>(item: childItem, selection: $selection)
}
.padding(.leading, 12.0)
}
}
}
@ -36,6 +52,10 @@ struct SourceItemGroup_Previews: PreviewProvider {
static var sampleItem = state.deviceStyleItems()[0]
static var previews: some View {
SourceItemGroup(selection: $selection, item: sampleItem)
List {
SourceItemGroup(item: sampleItem, selection: $selection)
SourceItemGroup(item: sampleItem, selection: $selection)
SourceItemGroup(item: sampleItem, selection: $selection)
}
}
}

View file

@ -15,10 +15,7 @@ struct SourceItemLink<Item: SourceItem>: View {
var body: some View {
NavigationLink(tag: item.id, selection: $selection,
destination: { SourceItemContent(item: item) },
label: {
SourceItemLabel(item: item)
.padding(.leading, 2.0)
}
label: { SourceItemLabel(item: item) }
)
}
}