Post

Replies

Boosts

Views

Activity

SwiftUI NavigationSplitView like Apple Music
In the Apple Music app on iPad (horizontal size class == .regular), when a selection is made from the Split View sidebar, the detail switches to a separate UINavigationController for that selection, where we can push/pop views. If we make a different selection from the sidebar, we get another UINavigationController to manipulate. If we return to the first selection, the detail view is still showing the stack contents for that controller. I am trying to get the same behavior from NavigationSplitView in SwiftUI, but the detail view will reset its presented controller to its root. I think this is because NavigationSplitView uses whatever NavigationStack it finds in the detail hierarchy to manage its contents, effectively erasing the per-view stack contents. I have tried various methods of saving and restoring the navigation path without any luck. Any ideas on how to approach this? I have included a very simple example to show what I'm talking about. import SwiftUI struct ExampleView: View { enum Selection: String, CaseIterable { case letters case numbers } @State private var selection: Selection? var body: some View { NavigationSplitView { List(selection: $selection) { ForEach(Selection.allCases, id: \.self) { selection in NavigationLink(value: selection) { Text(selection.rawValue.capitalized) } } } .navigationTitle("Sidebar") } detail: { switch selection { case .letters: self.lettersView case .numbers: self.numbersView default: Text("Make a selection") } } } var lettersView = LettersView() var numbersView = NumbersView() } struct ExampleView_Previews: PreviewProvider { static var previews: some View { ExampleView() } } // MARK: - struct LettersView: View { private let letters = ["a", "b", "c", "d", "e", "f"] @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { List { ForEach(letters, id: \.self) { letter in NavigationLink(value: letter) { Text(letter.uppercased()) } } } .navigationTitle("Letters") .navigationDestination(for: String.self) { letter in Text(letter.uppercased()).font(.largeTitle) } } } } // MARK: - struct NumbersView: View { private let numbers = Array(0..<6) @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { List { ForEach(numbers, id: \.self) { number in NavigationLink(value: number) { Text(String(number)) } } } .navigationTitle("Numbers") .navigationDestination(for: Int.self) { number in Text(String(number)).font(.largeTitle) } } } }
1
2
729
Jun ’23