I'm a little confused by the syntax of NavigationStack(path: Binding), as mentioned above, it looks like NavigationStack should automatically handle the updating of path when a NavigationLink is pressed, is this not the case?
I've implemented a basic view as below:
import SwiftUI
class PathObj: ObservableObject {
@State var path = [Int]()
}
struct Workout1: View {
@StateObject var pathObj = PathObj()
var body: some View {
NavigationStack(path: $pathObj.path) {
Text("Workout 1")
NavigationLink {
Workout2()
} label: {
VStack {
Text("Workout 2")
.font(.headline)
.foregroundStyle(.black)
Image(systemName: "arrow.right")
}
}
}
.environmentObject(pathObj)
}
}
The NavigationLink works correctly, but if I observe the environment object I can see that pathObj.paths is empty. Am I mis-understanding how this works? Below is Workout2's implementation:
import SwiftUI
struct Workout2: View {
@EnvironmentObject var pathObj: PathObj
var body: some View {
Text("Workout 2")
Button {
pathObj.path.removeAll()
} label: {
Text("Pop")
}
NavigationLink {
Workout3()
} label: {
VStack {
Text("Workout 3")
.font(.headline)
.foregroundStyle(.black)
Image(systemName: "arrow.right")
}
}
}
}
Where I try to add a pop function (remove all paths and navigate to root). I'm just playing with a few different implementations of handling multiple NavgationStacks on a Tab bar but feel like I'm missing the basic of passing a binding var to path?
Any help is much appreciated.
it looks like NavigationStack should automatically handle the updating of path
Yes.
but if I observe the environment object I can see that pathObj.paths is empty
This is because you used a destination-based navigation link. That is, you used one of the NavigationLink
initialisers that directly take in a destination:
as a view builder closure.
If you use a value-based navigation link, by calling one of the initialisers that take a value:
parameter, that value will be appended to the navigation path when the navigation link is activated. Note that the destination view will be written in a navigationDestination(for:destination:)
modifier.
// by activating this navigation link, 1 will be appended to the 'path' array
NavigationLink("Go!", value: 1)
.navigationDestination(for: Int.self) { value in
SomeDestination()
}
Destination-based navigation links do not affect the navigation path at all, so I recommend exclusively using value-based navigation links if you decide to use a navigation path, and not to mix the two types of navigation links.
Side note: in an ObservableObject
, @State
doesn't make much sense. I assume you meant to use @Published
.
class PathObj: ObservableObject {
@Published var path = [Int]()
}