3

I want to have a root NavigationStack that lets the user navigate around a SwiftUI app, including to a TabView with tabs that have their own navigation stack. Unfortunately, this seems to not work at all (xcode 14.2, iOS 16).

The following example demonstrates the issue. When you attempt to navigate inside the tab view navigation stack, the tabs disappear and then the app goes into a broken state where navigation basically stops working entirely.

import SwiftUI
struct TabsView: View {
 var body: some View {
 TabView {
 NavigationStack {
 ZStack {
 NavigationLink("Navigate to child tab", value: 1)
 }
 .navigationDestination(for: Int.self) { screen in
 Text("Tab child \(screen)")
 }
 }
 .tabItem {
 Label("Screen 1", systemImage: "house")
 }
 
 Text("Screen 2")
 .tabItem {
 Label("Screen 2", systemImage: "house")
 }
 }
 }
}
struct ContentView: View {
 var body: some View {
 NavigationStack {
 VStack {
 NavigationLink("Show Tabs", value: "tabs")
 }
 .navigationDestination(for: String.self) { screen in
 if screen == "tabs" {
 TabsView()
 } else {
 Text("?")
 }
 }
 }
 }
}

How can I make this work?

asked Dec 14, 2022 at 2:09
8
  • does this answer you question. Swift navigation bar not appearing. Commented Dec 14, 2022 at 6:03
  • 1
    Apple doesn’t want a TabView below a NavigstionView/Stack it must always be at the top this answer elaborates a little Commented Dec 14, 2022 at 7:57
  • But it works fine if I use the old NavigationView instead of the newer NavigationStack, so I don't think that's really the issue. Commented Dec 14, 2022 at 10:56
  • It just appears to look fine on iPhone the issues are clear if you try on iPad (Double column) and try to assign navigation title's, you end up having to hide navigation bars, etc. Apple has gone out of their way to enforce that they shouldn't be related. Commented Dec 14, 2022 at 12:50
  • 1
    You can also create your own tab view and all the issues are gone, it only takes a few lines of code. Commented Dec 14, 2022 at 13:00

2 Answers 2

0

Use NavigationView in ContentView. Apple has problems with NavigationStack in hierarchy of NavigationStack.

Sign up to request clarification or add additional context in comments.

1 Comment

NavigationView has been deprecated and Apple specifically states to move away from it and use NavigationStack instead. developer.apple.com/documentation/swiftui/…
0

Found solution for this one!

I am placing "top" NavigationStack with Color.clear initial view right after TabView in ZStack.

ZStack {
 tabBarView
 .zIndex(0)
 
 NavigationStack(path: $coordinator.topPath) {
 Color.clear
 .navigationDestination(for: CoordinatorService.Step.self) { destination in
 coordinator.resolve(pathItem: destination)
 }
 }
 .zIndex(1)
 .allowsHitTesting(!coordinator.topPath.isEmpty)
 .introspect(.navigationStack, on: .iOS(.v16, .v17)) {
 0ドル.viewControllers.forEach { controller in
 controller.view.backgroundColor = .clear
 }
 }
}
.environmentObject(coordinator)

We have to use Introspect library to remove that's NavigationStack's white background, because SwiftUI don't bring that possibility.

Also I am disabling hit testing on top navigation view when there are no views on top.

Check out full example project here:

https://github.com/thekingofsofa/TabNavigationStack/tree/main

EDIT 28.08.24:

We can now remove Introspect library and use ".containerBackground(.clear, for: .navigation)" in iOS 18 to have invisible background for top NavigationStack.

answered Nov 20, 2023 at 18:31

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.