1

I have three views in my project - ContentView, SecondView, ThirdView

enter image description here

I want to navigate from contentView to secondView and secondView to thirdView.

ContentView :-

import SwiftUI

struct ContentView: View {
    @State private var path = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $path) {
            Button {
                path.append("SecondView")
            } label: {
                Text("This is the first view")
                
            }
            .navigationDestination(for: String.self) { view2 in
                if view2 == "SecondView" {
                 SecondView()
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SecondView :-

import SwiftUI

struct SecondView: View {
    @State private var path = NavigationPath()
    var body: some View {
        NavigationStack(path: $path) {
            Button {
                path.append("ThirdView")
            } label: {
                Text("This is the second view")
                
            }
            .navigationDestination(for: String.self) { view2 in
                if view2 == "ThirdView" {
                 ThirdView()
                }
            }
        }
    }
}

struct SecondView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationStack {
            SecondView()
        }
    }
}

ThirdView :-


import SwiftUI

struct ThirdView: View {
    var body: some View {
        Text("This is the third view")
    }
}

struct ThirdView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationStack {
            ThirdView()
        }
    }
}

What is happening :-

Whenever I tap on the "This is the first view" button in my ContentView, I am navigated to SecondView and automatically navigated back to contentView.

What I want :-

I want to navigate from contentView to secondView and secondView to thirdView.

  • 1
    Does this answer your question? [Only root-level navigation destinations are effective for a navigation stack with a homogeneous path](https://stackoverflow.com/questions/74362455/only-root-level-navigation-destinations-are-effective-for-a-navigation-stack-wit) – lorem ipsum Nov 20 '22 at 19:53
  • Please only include relevant code in your question... things like your previews and imports are irrelevant and make your question harder to answer :) – Stoic Nov 20 '22 at 20:15
  • @loremipsum It works if all the views are in single swiftUi file. – Uday Chaudhary Nov 20 '22 at 20:38
  • @Stoic I get it, will take care. – Uday Chaudhary Nov 20 '22 at 20:41

1 Answers1

2

You shouldn't have multiple NavigationStacks in the hierarchy. You should have one and pass the path via a Binding.

struct ContentView: View {
    @State private var path = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $path) {
            Button {
                path.append("SecondView")
            } label: {
                Text("This is the first view")
                
            }
            .navigationDestination(for: String.self) { view in
                switch view {
                case "SecondView":
                    SecondView(path: $path)
                case "ThirdView":
                    ThirdView()
                default:
                    Text("Unknown")
                }
            }
        }
    }
}

struct SecondView: View {
    @Binding var path: NavigationPath
    var body: some View {
        Button {
            path.append("ThirdView")
        } label: {
            Text("This is the second view")
            
        }
    }
}

struct ThirdView: View {
    var body: some View {
        Text("This is the third view")
    }
}

struct SecondView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationStack {
            SecondView(path: .constant(NavigationPath()))
        }
    }
}
jnpdx
  • 45,847
  • 6
  • 64
  • 94
  • I cannot preview the secondView swiftUiFile, error says :- missing argument for parameter 'path' in call. Note :- I am using different swiftui files – Uday Chaudhary Nov 20 '22 at 20:27
  • @UdayChaudhary See my update -- often in previews you have to provide a `.constant` for `Binding` values that are expected to be passed in. – jnpdx Nov 20 '22 at 20:29
  • One more thing if you can help me with. When I am in the SecondView swiftUiFile and tap on the "This is the second view" button nothing happens. – Uday Chaudhary Nov 20 '22 at 20:37
  • Are you talking about in the Preview? – jnpdx Nov 20 '22 at 20:38
  • yes in the preview – Uday Chaudhary Nov 20 '22 at 20:40
  • If you want Navigation to work in the previews (which is probably *not* something that you actually want -- a preview should be generally for testing a single view). You'd need to include the `NavigationStack` logic (including the `.navigationDestination`) into your `Preview` code. I recommend that you don't do that and use the preview for previewing *one* view. Or, if you really do want to do that, use a preview of the `ContentView` and pass in an explicit `path` that brings you to `SecondView` – jnpdx Nov 20 '22 at 20:42