iosswiftswiftuiswiftui-tabviewswiftui-navigationview

SwiftUI Hide TabView bar inside NavigationLink views


I have a TabView and separate NavigationView stacks for every Tab item. It works well but when I open any NavigationLink the TabView bar is still displayed. I'd like it to disappear whenever I click on any NavigationLink.

struct MainView: View {
    @State private var tabSelection = 0

    var body: some View {
        TabView(selection: $tabSelection) {
            FirstView()
                .tabItem {
                    Text("1")
                }
                .tag(0)
            SecondView()
                .tabItem {
                    Text("2")
                }
                .tag(1)
        }
    }
}

struct FirstView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: FirstChildView()) { // How can I open FirstViewChild with the TabView bar hidden?
                Text("Go to...")
            }
            .navigationBarTitle("FirstTitle", displayMode: .inline)
        }
    }
}

I found a solution to put a TabView inside a NavigationView, so then after I click on a NavigationLink the TabView bar is hidden. But this messes up NavigationBarTitles for Tab items.

struct MainView: View {
    @State private var tabSelection = 0

    var body: some View {
        NavigationView {
            TabView(selection: $tabSelection) {
                ...
            }
        }
    }
}

struct FirstView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: FirstChildView()) {
                Text("Go to...")
            }
            .navigationBarTitle("FirstTitle", displayMode: .inline) // This will not work now
        }
    }
}

With this solution the only way to have different NavigationTabBars per TabView item, is to use nested NavigationViews. Maybe there is a way to implement nested NavigationViews correctly? (As far as I know there should be only one NavigationView in Navigation hierarchy).

How can I hide TabView bar inside NavigationLink views correctly in SwiftUI?


Solution

  • If we talk about standard TabView, the possible workaround solution can be based on TabBarAccessor from my answer on Programmatically detect Tab Bar or TabView height in SwiftUI

    Here is a required modification in tab item holding NavigationView. Tested with Xcode 11.4 / iOS 13.4

    demo

    struct FirstTabView: View {
        @State private var tabBar: UITabBar! = nil
    
        var body: some View {
            NavigationView {
                NavigationLink(destination:
                    FirstChildView()
                        .onAppear { self.tabBar.isHidden = true }     // !!
                        .onDisappear { self.tabBar.isHidden = false } // !!
                ) {
                    Text("Go to...")
                }
                .navigationBarTitle("FirstTitle", displayMode: .inline)
            }
            .background(TabBarAccessor { tabbar in   // << here !!
                self.tabBar = tabbar
            })
        }
    }
    

    Note: or course if FirstTabView should be reusable and can be instantiated standalone, then tabBar property inside should be made optional and handle ansbsent tabBar explicitly.