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 { var body: some View {
VStack { VStack {
NavigationView { NavigationView {
List { List(selection: $state.selection) {
Divider() Divider()
switch state.base { switch state.base {
@ -26,12 +26,12 @@ struct ContentView: View {
case let .device(_, item): case let .device(_, item):
ForEach(item.visibleChildren) { ForEach(item.visibleChildren) {
SourceItemGroup(selection: $state.selection, item: $0) SourceItemGroup(item: $0, selection: $state.selection)
} }
case let .runtime(_, item): case let .runtime(_, item):
ForEach(item.visibleChildren) { 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 children : [Child] { get set }
var visibleChildren : [Child] { get set } var visibleChildren : [Child] { get set }
var customImgDesc : SourceImageDesc? { get } var customImgDesc : SourceImageDesc? { get }
var isExpanded : Bool { get set }
} }
extension SourceItem { extension SourceItem {
@ -54,10 +55,21 @@ extension SourceItem {
return match || !visibleChildren.isEmpty 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 { class SourceItemVal<Model: SourceItemData, Child: SourceItem>: SourceItem {
@Published var visibleChildren : [Child] @Published var visibleChildren : [Child]
@Published var isExpanded : Bool
var id = UUID() var id = UUID()
var data : Model var data : Model
@ -70,6 +82,7 @@ class SourceItemVal<Model: SourceItemData, Child: SourceItem>: SourceItem {
self.children = children self.children = children
self.visibleChildren = children self.visibleChildren = children
self.customImgDesc = customImgDesc self.customImgDesc = customImgDesc
self.isExpanded = false
} }
} }
@ -78,4 +91,5 @@ class SourceItemNone: SourceItem {
var data = SourceItemDataNone() var data = SourceItemDataNone()
var children = [SourceItemNone]() var children = [SourceItemNone]()
var visibleChildren = [SourceItemNone]() var visibleChildren = [SourceItemNone]()
var isExpanded = false
} }

View file

@ -8,25 +8,41 @@
import SwiftUI import SwiftUI
struct SourceItemGroup<Item: SourceItem>: View { struct SourceItemGroup<Item: SourceItem>: View {
@State private var isExpanded = false // would like to move into Item @StateObject var item : Item
@Binding var selection: UUID? @Binding var selection : UUID?
@StateObject var item: Item
var body: some View { var body: some View {
if item.visibleChildren.count > 0 { HStack(spacing: 0) {
DisclosureGroup( let button = Button(action: {
isExpanded: $isExpanded) { let optionActive = NSApplication.shared.currentEvent?.modifierFlags.contains(.option) == true
ForEach(item.visibleChildren) { childItem in
SourceItemGroup<Item.Child>(selection: $selection, item: childItem)
}
} label: {
SourceItemLink(selection: $selection, item: item)
}
} withAnimation(.easeInOut(duration: 0.2)) {
else { 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) 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 sampleItem = state.deviceStyleItems()[0]
static var previews: some View { 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 { var body: some View {
NavigationLink(tag: item.id, selection: $selection, NavigationLink(tag: item.id, selection: $selection,
destination: { SourceItemContent(item: item) }, destination: { SourceItemContent(item: item) },
label: { label: { SourceItemLabel(item: item) }
SourceItemLabel(item: item)
.padding(.leading, 2.0)
}
) )
} }
} }