Skip to content

Instantly share code, notes, and snippets.

@shaps80
Created June 19, 2024 10:08
Show Gist options
  • Save shaps80/1a4114296d69e8626cdf3fc80a2098e6 to your computer and use it in GitHub Desktop.
Save shaps80/1a4114296d69e8626cdf3fc80a2098e6 to your computer and use it in GitHub Desktop.
Provides a simple subscript focused API for easily binding DisclosureGroup or Section expansions including persistence across app launches.
import SwiftUI
struct NamedExpansions: RawRepresentable {
@Observable
final class Wrapper {
var sections: Set<String>
init(sections: Set<String> = []) {
self.sections = sections
}
}
@Bindable
var wrapper: Wrapper = .init()
var rawValue: String {
wrapper.sections.joined(separator: "|")
}
init(rawValue: String = "") {
wrapper = .init(sections: Set(rawValue.components(separatedBy: "|")))
}
private func bind(to section: String) -> Binding<Bool> {
.init(
get: { !wrapper.sections.contains(section) },
set: { expanded in
if !expanded {
wrapper.sections.insert(section)
} else {
wrapper.sections.remove(section)
}
}
)
}
subscript(_ name: String) -> Binding<Bool> {
bind(to: name)
}
}
@shaps80
Copy link
Author

shaps80 commented Jun 19, 2024

Example:

struct Sidebar: View {
    @SceneStorage("expansions") private var expansions: NamedExpansions = .init()

    var body: some View {
        List {
            Section("Home", isExpanded: expansions["home"]) {
                // ...
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment