SwiftUI NavigationPath not updating with NavigationStack

this is the code

struct ContentView: View {
    @State var path = NavigationPath()
    var body: some View {
        NavigationStack(path: $path){
            List{
                NavigationLink {
                    View1(){
                        print(path.count)
                        print(path)
                    }
                } label: {
                    Text("level0 ")
                }
                
            }
        }
    }
}

struct View1: View {
    var go: () -> Void
    var body: some View {
        List{
            NavigationLink {
                View2(){
                    go()
                    print("went to view2")
                }
            } label: {
                Text("level 1 ")
            }
            
        }
        .onAppear(){
            print("view1 enter")
            go()
        }
    }
}

struct View2: View {
    var go: ()-> Void
    var body: some View {
        List{
            NavigationLink {
                View3(){
                    go()
                    print("went to view3")
                }
            } label: {
                Text("level 2 ")
            }
        }
        .onAppear(){
            print("view2 enter")
            go()
        }
    }
}
struct View3: View {
    var go: ()-> Void
    var body: some View {
        List{
            Text("level 3")
                .onAppear(){
                    print("view3 enter")
                    go()
                }
        }
    }
}

and this is the print log

view1 enter
0
NavigationPath(_items: SwiftUI.NavigationPath.(unknown context at $1c5c2c248).Representation.eager([]), subsequentItems: [], iterationIndex: 0)
view2 enter
0
NavigationPath(_items: SwiftUI.NavigationPath.(unknown context at $1c5c2c248).Representation.eager([]), subsequentItems: [], iterationIndex: 0)
went to view2

view3 enter
0
NavigationPath(_items: SwiftUI.NavigationPath.(unknown context at $1c5c2c248).Representation.eager([]), subsequentItems: [], iterationIndex: 0)
went to view2
went to view3

question

NavigationPath not updating with NavigationStack,

when I open view1 and view2 ,why NavigationPath not update?

Answered by Vision Pro Engineer in 775896022

Hi @zhifang ,

You'll need to use .navigationDestination to ensure that these views are getting appended to the NavigationPath. I put together some code that I'll paste below which may help. It uses a struct called Page that has a title and a destination. The navigation destination displays a view with a NavigationLink to the next view that has a link to the next and so on. I keep track of which page we're on with a "currentPage" variable. Take a look at the documentation here for more information. You'll see the path count getting printed each time you click on a NavigationLink.

struct ContentView: View {
    @State var path = NavigationPath()
    @State private var dests: [Page] = [.init(title: "level1", destination: "level2"), .init(title: "level2", destination: "level3"), .init(title: "level3", destination: "level4")]
    @State private var currPage: Int = 0
    
    var body: some View {
        NavigationStack(path: $path){
            ListView(dests: $dests, currPage: $currPage)
            
                .navigationDestination(for: String.self) {
                    _ in
                    ListView(dests: $dests, currPage: $currPage)
                        .onAppear {
                            print(path.count)
                            currPage += 1
                        }
                }
        }
    }
}
struct ListView: View {
    @Binding var dests: [Page]
    @Binding var currPage: Int
    
    var body: some View {
        List {
            NavigationLink(dests[currPage].title, value: dests[currPage].destination)
        }
    }
}

struct Page: Identifiable, Hashable {
    var id = UUID()
    var title: String
    var destination: String
    
    init(id: UUID = UUID(), title: String, destination: String) {
        self.id = id
        self.title = title
        self.destination = destination
    }
}
Accepted Answer

Hi @zhifang ,

You'll need to use .navigationDestination to ensure that these views are getting appended to the NavigationPath. I put together some code that I'll paste below which may help. It uses a struct called Page that has a title and a destination. The navigation destination displays a view with a NavigationLink to the next view that has a link to the next and so on. I keep track of which page we're on with a "currentPage" variable. Take a look at the documentation here for more information. You'll see the path count getting printed each time you click on a NavigationLink.

struct ContentView: View {
    @State var path = NavigationPath()
    @State private var dests: [Page] = [.init(title: "level1", destination: "level2"), .init(title: "level2", destination: "level3"), .init(title: "level3", destination: "level4")]
    @State private var currPage: Int = 0
    
    var body: some View {
        NavigationStack(path: $path){
            ListView(dests: $dests, currPage: $currPage)
            
                .navigationDestination(for: String.self) {
                    _ in
                    ListView(dests: $dests, currPage: $currPage)
                        .onAppear {
                            print(path.count)
                            currPage += 1
                        }
                }
        }
    }
}
struct ListView: View {
    @Binding var dests: [Page]
    @Binding var currPage: Int
    
    var body: some View {
        List {
            NavigationLink(dests[currPage].title, value: dests[currPage].destination)
        }
    }
}

struct Page: Identifiable, Hashable {
    var id = UUID()
    var title: String
    var destination: String
    
    init(id: UUID = UUID(), title: String, destination: String) {
        self.id = id
        self.title = title
        self.destination = destination
    }
}
SwiftUI NavigationPath not updating with NavigationStack
 
 
Q