No matter how it is set up, a complex 3 Columns NavigationSplitView with NavigationStack crashes or has inconsistent workflow.
Sidebar selection determines which content (or feature) is in Content.
Content (or feature) who is live (or selected) can control what the Details.
Details has to be Navigable, and navigationDestinations depend on each feature (selected Content), so they cannot be registered all under one root.
Options I have tried: (many more as well)
@State var sideBar: SideBar?
@State var content: Content?
NavigationSplitView(
sidebar: {
List(sidebar) { ... }
},
content: {
switch sidebar { ... }
},
detail: {
XXX what to put here?
}
).navigationSplitViewStyle(.balanced)
Each sidebar brings a set of routes, that depends on it. So in details I have tried multiple options
// this does not work as NavigationStack is not simple
// enough to be completely removed or recreated
// somehow it ties on the Scene and crashes when
// switching between sidebars
detail: {
switch sidebar {
case .a:
NavigationStack {
View()
.navigationDestination(...
}
}
}
// clearing the navigationPath just before switching
// sidebars, but still controlling a NavigationStack
// inside details does not work, nothing happens.
detail: {
switch sidebar {
case .a:
NavigationStack(navigationPath) {
View()
.navigationDestination(...
}
}
}
// Having an empty NavigationStack in details
// but registering the destinations inside the content.
// This works however, when switching between sidebar
// it also crashes sometimes or it shows the Warning triangle
// on the navigation stack, as destinations become unavailable.
content: {
switch sidebar {
case .a:
RootView()
.navigationDestination(...)
}
},
detail: {
NavigationStack { }
}
// Trying to clear out the path before switching
// does not work either.
content: {
switch sidebar {
case .a:
RootView()
.navigationDestination(...)
}
},
detail: {
NavigationStack(navigationPath) { }
}
After much debugging, I found a way that works.
Placing a single NavigationStack in the Details view and maintaining the NavigationPath somewhere. When switching between SideBar, I had to clear the path before allowing the NavigationSplitView to refresh it self and its Content.
I also had to set a specific .id() to the content view that is the sidebar, somehow, even when sidebar changes, the content is not being refreshed.
I have tested this on 16.4 iPhone, iPad and MacOs.