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!
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
})
}
}
}
}
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
.
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("")
}
I think it's system bug. I had same problem.
Here is my Solution
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
}
}
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)
})
}
}
}
}
If you get access to the boolean that sets whether or not you are showing your navigation bar, you can fix this issue. But its not pleasant - I think there must be a bug behind the issue here.
The NavigationView
that contains the TabView
has a modifier that governs if the nav bar shows. Something like this:
NavigationView {
NavigationLink(destination:
TabBarScreen(domainDependencies: domainDependencies).environmentObject(navState),
isActive: $navState.initialNavMainLink) {
EmptyView()
}.isDetailLink(false)
}
.navigationViewStyle(StackNavigationViewStyle())
//the property here governs hiding of nav bar:
.navigationBarHidden(navState.initialNavBarHidden)
Ive put that property ( initialNavBarHidden
) within my NavState class, which is an object that contains all the nav links etc for my entire app navigation. That object is placed in the @environment
so i can use it anywhere.
On the .onAppear
for each tab, if I set that property to false, and then true, using DispatchQueue.main.asyncAfter..
with a short gap between them, then the problem is fixed. As I say, its a hack, but it works. I could get nothing else to work after some days looking at this issue.
So I have a function on my navState class like this:
func tabBarBugFix() {
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.initialNavBarHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.00001) {
self.initialNavBarHidden = true
}
}
}
And I call it for onAppear
for each tab page, eg:
struct PostPage: View {
@EnvironmentObject var navState: NavState
var body: some View {
Text("Create a Post")
.onAppear() {
navState.tabBarBugFix()
}
}
}
You get a tiny visual glitch, which is horrible but brief. As a better fix Im actually going to take my tab bar out of the NavigationView altogether, as thats where the bug happens.
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
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.