SwiftUI : NavigationStack in new iOS 18 TabView pushes twice when path in parameter

Hello,

With iOS 18, when NavigationStack is in new TabView, with path parameter containing current navigation state is set, the navigation destination view is pushed twice.

See below with example that pushes twice on iOS 18 but is correct on iOS 17

@MainActor
class NavigationModel: ObservableObject {
    static let shared = NavigationModel()
    
    @Published var selectedTab: String
    @Published var homePath: [Route]
    @Published var testPath: [Route]
}


struct ContentView: View {
    @StateObject private var navigationModel: NavigationModel = NavigationModel.shared
    
    var body: some View {
        TabView(selection: $navigationModel.selectedTab){
            HomeView()
                .tabItem {
                    Label("Home", systemImage: "house")
                }
                .tag("home")
            
            TestView()
                .tabItem {
                    Label("Test", systemImage: "circle")
                }
                .tag("test")
        }
    }
}


struct HomeView: View {
    @StateObject private var navigationModel: NavigationModel = NavigationModel.shared

    var body: some View {
        NavigationStack(path: $navigationModel.homePath){
            VStack{
                Text("home")
                NavigationLink(value: Route.test1("test1")){
                    Text("Go to test1")
                }
            }
            .navigationDestination(for: Route.self){ route in
                NavigationModelBuilder.findFinalDestination(route:route)
            }
        }
    }
}

I don't what causes the issue because it works well on iOS 16 and iOS 17. I think the path is somehow reset but I don't why (maybe by the TabView ?)

Note that the bug only occurs with TabView. Don't really know if it is a TabView bug or if it is on my side.

I filed a feedback with sample project FB14312064

Answered by brebispanique in 799115022

The issue seems to be fixed in iOS 18 beta 5

It seems that this issue still hasn’t been resolved in the official release of iOS 18. As mentioned in the original post, it appears to be related to a problem with TabView and NavigationStack. While using a Path-based solution does fix the issue, there are some instability concerns, such as multiple screens being popped when using the back gesture. Most importantly, I prefer using the NavigationLink(value:...) format, so I hope this issue is addressed soon.

This makes my app unusable on the iOS 18 SDK, so I need to stay with Xcode 15 for now. No amount of removing the path from the NavigationStack, or using NavigationPath, helped.

Hi everyone,

I'm also experiencing the double-push issue with NavigationLink in iOS 18, especially when used within a TabView. This bug has been incredibly frustrating, as it disrupts the user experience significantly.

As a workaround, I've reverted to using the old-style NavigationLink with a destination and label, which thankfully seems to avoid the issue, but it's far from an ideal solution.

Is there any update or a way to track the status of this bug? It would be great to know if Apple is working on a fix.

Thanks, Ruben

I found that using the new Tab API (https://developer.apple.com/documentation/swiftui/tab) on iOS 18 resolves the problem for me.

The issue isn't fixed and still can be represented on iOS 18.0

The solution of @kh_bb helps for the most of cases but the issue can be representated in some specific cases.

@cutecutealien it didn't help me, unfortunately. Can you please send you example?

One thing I noticed is that I had some errant selection: parameters in some Lists and after removing them, the behavior stopped.

Has anyone found a workaround for this? I cannot have a NavigationStack inside a TabView without it double pushing.

I’m not familiar with all the details, but I found a workaround for this issue. Simply set the constant tabViewCustomization to the TabView.

.tabViewCustomization(.constant(TabViewCustomization()))

This issue appears to have been resolved in iOS 18.1 and Xcode 16.1. (At least in my app, it displays correctly.)

SwiftUI : NavigationStack in new iOS 18 TabView pushes twice when path in parameter
 
 
Q