Search code examples
iosswiftuiswiftui-navigationlinkswiftui-navigationview

NavigationLink back not working with @Binding


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?


Solution

  • 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")
                }
            }
        }
    }