I have three views
A,B and C. User can navigate from A to B and from A to C. User can navigate from B to C. Now I want to differentiate if the user have come from A to C or from B to C so I was looking in how to pass extra data in NavigationStack which can help me differentiate
Below is my code
import SwiftUI
@main
struct SampleApp: App {
@State private var path: NavigationPath = .init()
var body: some Scene {
WindowGroup {
NavigationStack(path: $path){
A(path: $path)
.navigationDestination(for: ViewOptions.self) { option in
option.view($path)
}
}
}
}
enum ViewOptions {
case caseB
case caseC
@ViewBuilder func view(_ path: Binding<NavigationPath>) -> some View{
switch self{
case .caseB:
B(path: path)
case .caseC:
C(path: path)
}
}
}
}
struct A: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("A")
Button {
path.append(SampleApp.ViewOptions.caseB)
} label: {
Text("Go to B")
}
Button {
path.append(SampleApp.ViewOptions.caseC)
} label: {
Text("Go to C")
}
}
}
}
struct B: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("B")
Button {
path.append(SampleApp.ViewOptions.caseC)
} label: {
Text("Go to C")
}
}
}
}
struct C: View {
@Binding var path: NavigationPath
var body: some View {
VStack {
Text("C")
}
}
}
2
Answers
Instead of "pass extra data in
NavigationStack
" you can pass data in aNavigationRouter
. It gives you much more controlOnce you have access to the router in the
View
s you can adjust accordingly.You can read the second-to-last item in the
path
property to learn what the previous screen was.To do this, it’s easier to use an actual array of
ViewOptions
as the path, instead of aNavigationPath
.For example:
Remember, a
NavigationPath
is nothing more than a type-erased array. It can be used to build aNavigationStack
quickly without having to worry that all destination values have to match the same type. Since as you’re controlling the navigation flow with your own typeViewOptions
, it makes no sense to useNavigationPath
.