State Restoration for DisclosureGroup Expansion in SwiftUI List Rows

KD Knowledge Diet
2 min readDec 9, 2024

--

State restoration is crucial for providing a seamless user experience when working with complex SwiftUI interfaces. While it’s straightforward to save simple types using SceneStorage, handling advanced use cases, such as maintaining the expansion state of DisclosureGroups within List rows, requires additional effort. In this guide, we’ll explore how to implement state restoration for DisclosureGroup expansion in SwiftUI List rows.

Scenario Overview:

Consider a scenario where you have a list of network request groups, and you want to display them in a List view with DisclosureGroups for each group. To enhance the user experience, you’d like to preserve the expansion state of these DisclosureGroups even when the app is closed and reopened.

1. Define the State Restoration Key:
To achieve state restoration for DisclosureGroup expansion, you need to associate a unique key with each group. In this example, we’ll use the group’s UUID as the key. You can define a function to generate this key:

func restorationKey(for group: RequestGroup) -> String {
return "RequestGroup_\(group.id.uuidString)"
}

2. Store the Expansion State in SceneStorage:
To store the expansion state, create a SceneStorage property for each group’s expansion state using the previously defined restoration key:

@SceneStorage("expandedGroups")
var expandedGroups: Set<String> = []

3. Update the DisclosureGroups:
Within your List view, update the DisclosureGroups to include a binding for their expansion state. Use the restoration key to determine whether a group should be expanded or collapsed:

List {
ForEach(requestGroups) { group in
DisclosureGroup(
isExpanded: Binding(
get: {
expandedGroups.contains(restorationKey(for: group))
},
set: { isExpanded in
if isExpanded {
expandedGroups.insert(restorationKey(for: group))
} else {
expandedGroups.remove(restorationKey(for: group))
}
}
),
content: {
Text(group.name)
ForEach(group.requests) { request in
Text(request.url)
}
}
)
}
}

By using a binding for the `isExpanded` parameter of DisclosureGroup, you can read and write the expansion state based on whether the restoration key is in the `expandedGroups` set.

4. Test State Restoration:
Build and run your SwiftUI app. You should now see that the expansion state of DisclosureGroups is preserved even when you close and reopen the app.

Conclusion:

Implementing state restoration for DisclosureGroup expansion within SwiftUI List rows enhances the user experience by maintaining the state of collapsed and expanded groups across app sessions. By using SceneStorage to store the expansion state and providing bindings to DisclosureGroups, you can ensure a consistent and seamless user interface for your app, improving usability and user satisfaction.

--

--

KD Knowledge Diet
KD Knowledge Diet

Written by KD Knowledge Diet

Software Engineer, Mobile Developer living in Seoul. I hate people using difficult words. Why not using simple words? Keep It Simple Stupid!

No responses yet