Last active
January 31, 2024 02:24
-
-
Save d4rkd3v1l/0321faf11a877adefea7c96d0b1f67d6 to your computer and use it in GitHub Desktop.
SwiftUI: DisclosureGroup "expansion handler" to only have one group expanded at a time, and automatically hiding the last one, when expanding a new one.
This file contains 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 characters
class ExpansionHandler<T: Equatable>: ObservableObject { | |
@Published private (set) var expandedItem: T? | |
func isExpanded(_ item: T) -> Binding<Bool> { | |
return Binding( | |
get: { item == self.expandedItem }, | |
set: { self.expandedItem = $0 == true ? item : nil } | |
) | |
} | |
func toggleExpanded(for item: T) { | |
self.expandedItem = self.expandedItem == item ? nil : item | |
} | |
} | |
// Usage: | |
// Some `Equatable` type, can also use basic types like `String` or `Date`. | |
enum ExpandableSection: Equatable { | |
case section | |
case anotherSection | |
} | |
@StateObject private var expansionHandler = ExpansionHandler<ExpandableSection>() | |
DisclosureGroup( | |
isExpanded: self.expansionHandler.isExpanded(.section), | |
content: { | |
// ... | |
}, | |
label: { | |
// ... | |
} | |
) | |
.contentShape(Rectangle()) // Usability feature to have the whole item tappable, and not just the label/disclosure indicator | |
.onTapGesture { | |
withAnimation { self.expansionHandler.toggleExpanded(for: .section) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works as a charm! Kudos!!! 🚀🚀🚀