'SwiftUI how to hide navigation bar with TabView

I'm using SwiftUI TabView inside NavigationView, But I just can't hide the navigation bar in iOS 13.0 simulator.

Here is the code:

import SwiftUI

struct TestView: View {
    var body: some View {
        ZStack {
            Color.green
            Text("Hello")
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red
                TabView(selection: .constant(0),
                        content: {
                            TestView()
                                .tabItem { Text("test") }
                                .tag(0)
                                .navigationBarTitle("")
                                .navigationBarHidden(true)
                        })
            }

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }

}

Any help? thanks!

enter image description here



Solution 1:[1]

Check this

TabView {
        ECHomeView().tabItem {
            VStack {
                Text("Home")
                Image.Home.renderingMode(.template)
            }
        }.navigationBarHidden(true)
        ECMyClaimsView().tabItem {
            VStack {
                Text("My Claims")
                Image.Myclaims.renderingMode(.template)
            }
        }.navigationBarHidden(true).navigationBarTitle("")
        ECAddClaimView().tabItem {
            VStack {
                Text("Create")
                Image.Create.renderingMode(.template)
            }
        }.navigationBarHidden(true).navigationBarTitle("")
        ECMyApprovalsView().tabItem {
            VStack {
                Text("My Approvals")
                Image.MyApprovals.renderingMode(.template)
            }
        }.navigationBarHidden(true).navigationBarTitle("")
        ECMenuView().tabItem {
            VStack {
                Text("Menu")
                Image.Menu.renderingMode(.template)
            }
        }.navigationBarHidden(true).navigationBarTitle("")
    }

Solution 2:[2]

I think it's system bug. I had same problem.

Same issue

Here is my Solution

1. Add UIApplication extension

https://stackoverflow.com/a/30858591/12496427

extension UIApplication {
    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let navigationController = controller as? UINavigationController {
            return topViewController(controller: navigationController.visibleViewController)
        }
        if let tabController = controller as? UITabBarController {
            if let selected = tabController.selectedViewController {
                return topViewController(controller: selected)
            }
        }
        if let presented = controller?.presentedViewController {
            return topViewController(controller: presented)
        }
        return controller
    }
}

2. Using it in onAppear() function

struct TestView: View {
    var body: some View {
        ZStack {
            Color.green
            Text("Hello")
        }
/////// HERE ////////
        .onAppear { 
            UIApplication.topViewController()?
               .navigationController?.isNavigationBarHidden = true
        }
/////// HERE ////////
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red
                TabView(selection: .constant(0),
                        content: {
                            TestView()
                                .tabItem { Text("test") }
                                .tag(0)
                                .navigationBarTitle("")
                                .navigationBarHidden(true)
                        })
            }

        }
    }
}

Solution 3:[3]

you have already hide the navigation bar with .navigationBarHidden(true). here you are seeing the safe area , so you can let your view expand in to the safe area by using .ignoresSafeArea()

struct ContentView: View {
    var body: some View {
        NavigationView {
            ZStack {
                Color.red
                
                TabView(selection: .constant(0),
                        content: {
                            TestView()
                                .tabItem { Text("test") }
                                .tag(0)
                                .navigationBarTitle("")
                                .navigationBarHidden(true)
                                .ignoresSafeArea() //<-here
                        })
            }
            
        }
    }
}

enter image description here enter image description here

Solution 4:[4]

In the View you want to hide the NavigationView use .navigationBarHidden(true) to hide it.

struct TestView: View {
    var body: some View {
        ZStack {
            Color.green
            Text("Hello")
        }
        .navigationBarHidden(true)
    }
}

If you don't want the big NavigationView, use .navigationBarTitleDisplayMode(.inline) to shrink the size, and also keep using ToolBarItems.

Solution 5:[5]

How about the negative padding trick?

struct ContentView: View {
  var body: some View {
    NavigationView {
      TabView {
        List(1 ..< 40, id: \.self) {
          Text("A" + $0.description)
        }.tag(1).navigationBarHidden(true).navigationBarTitleDisplayMode(.inline)
        List(1 ..< 40, id: \.self) {
          Text("B" + $0.description)
        }.tag(2).navigationBarHidden(true).navigationBarTitleDisplayMode(.inline)
      }.padding(.bottom, -50) // <- trick
    }
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thomas Paul
Solution 2 Harry Kim
Solution 3
Solution 4 Yuto
Solution 5