I have a simple NavigationSplitView with various detail views and I want to preserve the navigation state in each of these detail views when the user switches detail views. But it seems that the navigation path is always reset when switching views.
//
// ContentView.swift
// Test
//
// Created by Miles Egan on 6/13/24.
//
import SwiftUI
enum SelectedView {
case first, second
}
enum DetailItem: String, CaseIterable, Hashable {
case one, two, three
}
struct DetailView: View {
let label: String
var body: some View {
VStack {
Text(label)
ForEach(DetailItem.allCases, id: \.self) { item in
NavigationLink(item.rawValue, value: item)
}
}
.navigationTitle(label)
}
}
struct ContentView: View {
@State private var selectedItem = SelectedView.first
@State private var firstPath = NavigationPath()
@State private var secondPath = NavigationPath()
var body: some View {
NavigationSplitView {
List(selection: $selectedItem) {
Text("First")
.tag(SelectedView.first)
Text("Second")
.tag(SelectedView.second)
}
} detail: {
ZStack {
NavigationStack(path: $firstPath) {
DetailView(label: "First Start")
.opacity(selectedItem == .first ? 1 : 0)
.navigationDestination(for: DetailItem.self) { item in
DetailView(label: item.rawValue)
}
}
NavigationStack(path: $secondPath) {
DetailView(label: "Second Start")
.opacity(selectedItem == .second ? 1 : 0)
.navigationDestination(for: DetailItem.self) { item in
DetailView(label: item.rawValue)
}
}
}
}
}
}
For example. Try this and navigate a few times when the left sidebar is on the first item. Then switch to the second item. Then back to the first item. The state of the detail view is always reset instead of being preserved. It doesn't work if I let SwiftUI manage the navigation paths instead of providing them myself either.
@milesegan You could try using a navigation link to perform navigation based on a presented data value:
NavigationSplitView {
List {
NavigationLink("First", value: SelectedView.first)
NavigationLink("Second", value: SelectedView.second)
}
} detail: {
....
}
Keep in mind that, If your List has a selection binding and it is of the same type as the navigation Link; when you activate the link, it will be added to the value of the lists selection and that resets the NavigationStack path.