iOS 18 beta bug: NavigationStack pushes the same view twice

Hello, community and Apple engineers. I need your help.

Our app has the following issue: NavigationStack pushes a view twice if the NavigationStack is inside TabView and NavigationStack uses a navigation path of custom Hashable elements.

Our app works with issues in Xcode 18 Beta 13 + iOS 18.0. The same issue happened on previous beta versions of Xcode 18. The issue isn’t represented in iOS 17.x and everything worked well before iOS 18.0 beta releases.

I was able to represent the same issue in a clear project with two simple views. I will paste the code below.

Several notes:

  • We use a centralised routing system in our app where all possible routes for navigation path are implemented in a View extension called withAppRouter().
  • We have a enum RouterDestination that contains all possible routes and is resolved in withAppRouter() extension.
  • We use Router class that contains @Published var path: [RouterDestination] = [] and this @Published property is bound to NavigationStack. In the real app, we need to have an access to this path property for programmatic navigation purposes.
  • Our app uses @ObservableObject / @StateObject approach.
import SwiftUI

struct ContentView: View {
    @StateObject private var router = Router()
 
    var body: some View {
        TabView {
            NavigationStack(path: $router.path) {
                NavigationLink(value: RouterDestination.next, label: {
                                            Label("Next", systemImage: "plus.circle.fill")
                                        })
                        .withAppRouter()
            }
       }
    }
}

enum RouterDestination: Hashable {
    case next
}

struct SecondView: View {
    var body: some View {
       Text("Screen 2")
    }
}

class Router: ObservableObject {
    @Published var path: [RouterDestination] = []
}

extension View {
    func withAppRouter() -> some View {
        navigationDestination(for: RouterDestination.self) { destination in
            switch destination {
            case .next:
                return SecondView()
            }
        }
    }
}

Below you can see the GIF with the issue:

What I tried to do:

  1. Use iOS 17+ @Observable approach. It didn’t help.
  2. Using @State var path: [RouterDestination] = [] directly inside View seems to help. But it is not what we want as we need this property to be @Published and located inside Router class where we can get an access to it, and use for programmatic navigation if needed.

I ask Apple engineers to help with that, please, and if it is a bug of iOS 18 beta, then please fix it in the next versions of iOS 18.0

I found a similar issue reported by other developers here: https://developer.apple.com/forums/thread/759542 so the problem really exists and seems to be a bug

iOS 18 beta bug: NavigationStack pushes the same view twice
 
 
Q