1

My app supports iOS 15.0 so, I can not use NavigationPath. So, I've added NavigationView and used NavigationLink for navigation. Here is my simple app flow.

FirstView -> SecondView -> ThirdView -> ForthView

I want to navigate from ForthView to SecondView. But Navigating back is not working. Here is my code for same.

struct FirstView: View {
    @State private var isActive: Bool = false
    var body: some View {
        VStack(spacing: 8) {
            Label("Hello, world!", systemImage: "globe")
            NavigationLink(destination: SecondView(), isActive: $isActive) {
                Button {
                    isActive = true
                } label: {
                    Text("Second")
                }
            }
        }
        .padding()
    }
}

struct SecondView: View {
    @State private var isActive: Bool = false
    var body: some View {
        VStack(spacing: 8) {
            Text("Hello, World!")
            NavigationLink(destination: ThirdView(shouldGoToSecond: $isActive), isActive: $isActive) {
                Button {
                    isActive = true
                } label: {
                    Text("Third")
                }
            }
        }
        .navigationTitle("Second")
    }
}

struct ThirdView: View {
    @Binding var shouldGoToSecond: Bool
    @State private var isActive: Bool = false
    var body: some View {
        VStack {
            Text("Hello, World!")
            NavigationLink(destination: ForthView(shouldGoToSecond: $shouldGoToSecond), isActive: $isActive) {
                Button {
                    isActive = true
                } label: {
                    Text("Go to Forth")
                }
            }
        }
        .navigationTitle("Third")
    }
}

struct ForthView: View {
    @Binding var shouldGoToSecond: Bool
    var body: some View {
        VStack {
            Text("Hello, World")
            Button {
                shouldGoToSecond = false
            } label: {
                Text("Go to Second")
            }
        }
    }
}

I'm using the @State variable to activate the navigation link and passing it to the next views via @Binding but it is not working. What am I missing here?

Mrugesh Tank
  • 3,495
  • 2
  • 29
  • 59

3 Answers3

2

You can achieve it by using isDetailLink property of NavigationLink when you have multiple navigations.

struct FirstView: View {
    @State private var isActive: Bool = false
    var body: some View {
        
        NavigationView {
            VStack(spacing: 8) {
                Label("Hello, world!", systemImage: "globe")
                NavigationLink(destination: SecondView1(), isActive: $isActive) {
                    Button {
                        isActive = true
                    } label: {
                        Text("Second")
                    }
                }.isDetailLink(false) //<---
            }
            .padding()
            
        }
    }
}

struct SecondView: View {
    @State private var isActive: Bool = false
    var body: some View {
        VStack(spacing: 8) {
            Text("Hello, World!")
            NavigationLink(destination: ThirdView(shouldGoToSecond: $isActive), isActive: $isActive) {
                Button {
                    isActive = true
                } label: {
                    Text("Third")
                }
            }
        }
        .navigationTitle("Second")
        
    }
}

struct ThirdView: View {
    @Binding var shouldGoToSecond: Bool
    @State private var isActive: Bool = false
    var body: some View {
        VStack {
            Text("Hello, World!")
            NavigationLink(destination: ForthView(shouldGoToSecond: $shouldGoToSecond), isActive: $isActive) {
                Button {
                    isActive = true
                } label: {
                    Text("Go to Forth")
                }
            }
        }
        .navigationTitle("Third")
    }
}

struct ForthView: View {
    @Binding var shouldGoToSecond: Bool
    var body: some View {
        VStack {
            Text("Hello, World")
            Button {
                shouldGoToSecond = false
            } label: {
                Text("Go to Second")
            }
        }
    }
}
Hardik Shekhat
  • 1,680
  • 12
  • 21
1

here is few steps to handle golbal navigation (No required to send flag or Binding)

1

Create your global class

class Network: NSObject, ObservableObject {

    @Published var moveToHome: Bool = false 
}

2

where you want to pop root file then change moveToHome flag

make you assign that class in your view class like this

 @EnvironmentObject var network: Network

then change flag on yout button or after get API response

self.network.moveToHome = true

3

go to your home class and call onReceive method before dismiss to home, chnage flag for next time

            .onReceive(self.network.$moveToHome) { moveToDashboard in
                        if moveToDashboard {
                            print("Move to dashboard: \(moveToDashboard)")
                            self.presentation.wrappedValue.dismiss()
                            self.network.moveToHome = false
                        }
            }

Note: Suppose your Home class is Home or Dashboard name and then your navigate go to View1, View2, View3, .....viewN where you want to present Root change that class only flag like i want to pop after last ViewN then put that flag on ViewN or you want to root after Third then Put on Third View3

self.network.moveToHome = true

after that come where you have main Root, call on onReceive on same class. Suppose i want to back Home class then put onReceive in View1.... Mean one class added -> Home+(Navigate) That's it!

hope this is helpful or let me know if you have any queries

Krishna kushwaha
  • 275
  • 2
  • 11
0

You should use

@Environment(\.presentationMode) var presentaionMode

  • This is working perfectly fine for navigating back for single view only. I want to navigate back 2 views. From `ForthView` to `SecondView` – Mrugesh Tank Apr 05 '23 at 11:59
  • Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Jeremy Caney Apr 07 '23 at 00:04
  • @MrugeshTank you can use global observation file and change the flag and call onReciebved after flag changes and dismiss to present. Let me know if you got it or need to share demo app – Krishna kushwaha Apr 19 '23 at 14:10
  • @Krishnakushwaha Do I need to handle navigation on that Global observation file? – Mrugesh Tank Apr 21 '23 at 05:14