Search code examples
swiftuiswiftui-navigationlinkswiftui-navigationview

Remove specific screen from NavigationView in SwiftUI


Currently i am using NavigationView->NavigationLink to navigate one screen to another. How can i remove specific screen from NavigationView?

For Example I have four screen A, B, C and D. The navigation chain like this A->B-C->D. From Screen D how can i go back in Screen B and then Sceen A


Solution

  • To achieve this, you need to the new NavigationStack for iOS 16 which allows programmatic navigation.

    The NavigationStack takes a path parameter; and array that you add or remove objects to, representing your navigation stack. Use the navigationDestination modifier to decide which actual views to push on the stack based on the contents of the path.

    Example:

    enum NavView {
        case b, c, d
    }
    
    struct ContentView: View {
        
        @State private var path: [NavView] = []
        
        var body: some View {
            NavigationStack(path: $path) {
                VStack {
                    NavigationLink("Show B", value: NavView.b)
                        .navigationTitle("View A")
                }
                .navigationDestination(for: NavView.self) { view in
                    switch view {
                    case .b: ViewB(path: $path)
                    case .c: ViewC(path: $path)
                    case .d: ViewD(path: $path)
                    }
                }
            }
        }
    }
    
    struct ViewB: View {
        @Binding var path: [NavView]
        var body: some View {
            NavigationLink("Show C", value: NavView.c)
                .navigationTitle("View B")
        }
    }
    
    struct ViewC: View {
        @Binding var path: [NavView]
        var body: some View {
            Button("Show D", action: { path.append(NavView.d) })
                .navigationTitle("View C")
        }
    }
    
    struct ViewD: View {
        @Binding var path: [NavView]
        var body: some View {
            Button("Back to B", action: { path.removeLast(2) })
                .navigationTitle("View D")
        }
    }
    

    Note that the navigationDestination modifier is not on the NavigationStack, but one one of its contained views.

    enter image description here