navigation is happening 2 times only

52 Views Asked by At

I have code as below.

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        TabView {
            
            NavigationStack {
                NavigationLink("Tap Me") {
                    Text("Detail View")
                        .toolbar(.hidden, for: .tabBar)
                }
                .navigationTitle("Primary View")
            }
            .tabItem {
                Label("Home", systemImage: "house")
            }
        }
    }
}

#Preview {
    ContentView()
}

When I click Tap Me it takes me to details & when click back it take back from details, which is fine. If I try this multiple times, navigation is happening only 2 times which is weird.

Any idea why this is happening?

2

There are 2 best solutions below

0
Manish Ahire On

Use NavigationLink with value, which is used by NavigationDestination to present the next view.

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        TabView {
            
            HomeView()
                .tabItem {
                    Label("Home", systemImage: "house")
                }
        }
        
    }
}

struct HomeView: View {
    var body: some View {
        
        NavigationStack {
            
            NavigationLink("Tap Me", value: 1)
            
            
            .navigationDestination(for: Int.self) { value in
                Text("Detail View")
            }
            
            .navigationTitle("Primary View")
        }
        
        
    }
}


#Preview {
    ContentView()
}
0
Mahi Al Jawad On

Solution to your problem

You can maintain a NavigationPath to track the destination. Example code for your view:

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            HomeView()
                .tabItem {
                    Label("Home", systemImage: "house")
                }
        }
    }
}

struct HomeView: View {
    enum Destination {
        case detailView
    }
    
    @State var navPath: NavigationPath = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $navPath) {
            NavigationLink("Tap Me", value: Destination.detailView)
            /*
             // Alternatively you can do this:
            Button("Tap Me") {
                navPath.append(Destination.detailView)
            }
             */
            .navigationTitle("Primary View")
            .navigationDestination(for: Destination.self) { destination in
                switch destination {
                case .detailView:
                    Text("Detail View")
                        .toolbar(.hidden, for: .tabBar)
                }
            }
        }
    }
}

Output simulation:

enter image description here

Reason of the problem

It only happens when the NavigationStack is inside the TabView. Investing a couple of hours I came to the conclusion that, It's a SwiftUI bug in NavigationLink when used without a Hashable value inside a TabView.

Bonus

If you want more elegant and cleaner approach for navigation you can check this out: https://github.com/MahiAlJawad/Clean-Code-Navigation-SwiftUI