NavigationStack not affected by EnvironmentObject changes

The reason your code is not working is that you haven’t added anything to your path, so your path is empty. You can simply verify this by adding print(path.count) in your popToRoot method it will print 0 in the console.

To work with NavigationPath you need to use navigationDestination(for:destination:) ViewModifier, So for your example, you can try something like this.

ContentView:- Change NavigationStack like this.

NavigationStack(path: $navigationCoordinator.path) {
    VStack {
        NavigationLink(value: 1) {
            Text("Go To SecondView")
        }
    }
    .navigationDestination(for: Int.self) { i in
        if i == 1 {
            SecondView()
        }
        else {
            ThirdView()
        }
    }
}

SecondView:- Change NavigationLink like this.

NavigationLink(value: 2) {
    Text("Go To ThirdView")
}

This workaround works with Int but is not a better approach, so my suggestion is to use a custom Array as a path. Like this.

enum AppView {
    case second, third
}

class NavigationCoordinator: ObservableObject {
    @Published var path = [AppView]()
}

NavigationStack(path: $navigationCoordinator.path) {
    FirstView()
        .navigationDestination(for: AppView.self) { path in
            switch path {
            case .second: SecondView()
            case .third: ThirdView()
            }
        }
}

Now change NavigationLink in FirstView and SecondView like this.

NavigationLink(value: AppView.second) {
    Text("Go To SecondView")
}

NavigationLink(value: AppView.third) {
    Text("Go To ThirdView")
}

The benefit of the above is now you can use the button as well to push a new screen and just need to append in your path.

path.append(.second)
//OR
path.append(.third)

This will push a respected view.

For more details, you can read the Apple document of NavigationLink and NavigationPath.

Leave a Comment