mirror of
https://github.com/yattee/yattee.git
synced 2026-10-24 05:32:53 +00:00
Keep a section's stack when the sidebar selection changes
In the split-view sidebar layout (macOS, and now iPad and the iPhone Duo), the detail NavigationStack that a selection change replaces writes an empty path through its binding on the way out, so going to another section and back always landed on the section's root. macOS already behaved this way before the router. Only the selected section's stack is on screen and can pop, so path writes for any other section are ignored.
This commit is contained in:
@@ -44,7 +44,15 @@ final class NavigationRouter {
|
||||
let key = item.id
|
||||
return Binding(
|
||||
get: { self.stacks[key] ?? [] },
|
||||
set: { self.stacks[key] = $0 }
|
||||
set: {
|
||||
// Only the selected section's stack is on screen, so only it
|
||||
// edits its path (Back, swipe back). A NavigationSplitView
|
||||
// detail stack that is being replaced on a selection change
|
||||
// writes an empty path on its way out, which would throw
|
||||
// away what the section had pushed.
|
||||
guard key == self.selection.id else { return }
|
||||
self.stacks[key] = $0
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -677,6 +677,28 @@ struct NavigationCoordinatorTests {
|
||||
#expect(router.selection == .bookmarks)
|
||||
}
|
||||
|
||||
@Test("A stack that is no longer selected can't clear itself")
|
||||
func offscreenStackWriteIgnored() {
|
||||
let router = NavigationRouter()
|
||||
router.push(.history)
|
||||
let homePath = router.path(for: .home)
|
||||
|
||||
router.select(.bookmarks)
|
||||
homePath.wrappedValue = []
|
||||
|
||||
#expect(router.stack(for: .home) == [.history])
|
||||
}
|
||||
|
||||
@Test("The selected stack still pops")
|
||||
func selectedStackPops() {
|
||||
let router = NavigationRouter()
|
||||
router.push(.history)
|
||||
|
||||
router.path(for: .home).wrappedValue = []
|
||||
|
||||
#expect(router.stack(for: .home).isEmpty)
|
||||
}
|
||||
|
||||
@Test("A destination pushed before startup keeps its section")
|
||||
func deepLinkBeforeStartup() {
|
||||
let coordinator = NavigationCoordinator()
|
||||
|
||||
Reference in New Issue
Block a user