简体   繁体   中英

Navigation Bar hide is not working in SwiftUI

I'm having Three Views. I want to hide the navigation bar in the third View. Even if I give .navigationBarHidden(true) the navigation bar is displaying!

I couldn't find where I'm doing wrong. I've attached my code and the resulting screenshot below.

Xcode version - 11.1

struct ContentViewOne: View {
    var body: some View {
        NavigationView {
            ZStack {
                
                Color.yellow.edgesIgnoringSafeArea(.all)
                VStack(spacing: 20) {
                    Text("View One")
                    
                    NavigationLink(destination: ContentViewTwo()) {
                        Text("Navigate to View Two")
                            .foregroundColor(.white)
                            .padding()
                            .background(Color.red)
                    }
                }
            }
            .navigationBarTitle("View One")
        }
    }
}

struct ContentViewTwo: View {
    var body: some View {
        
        ZStack {
            Color.green.edgesIgnoringSafeArea(.all)
            VStack(spacing: 20) {
                Text("View Two")
                NavigationLink(destination: ContentViewThree()) {
                    Text("Navigate to View Three")
                        .foregroundColor(.white)
                        .padding()
                        .background(Color.red)
                }
            }
        }
        .navigationBarTitle("View Two")
    }
}

struct ContentViewThree: View {
    var body: some View {
        ZStack {
            Color.gray.edgesIgnoringSafeArea(.all)
            Text("View Three")
        }
        .navigationBarTitle("View Three")
        .navigationBarHidden(true)
        .navigationBarBackButtonHidden(true)
    }
}

在此处输入图像描述

NOTE: (For some reason it works in some cases) SwiftUI requires that you need to .navigationBarTitle for .navigationBarHidden to work properly.

NavigationView {
    ScrollView() {
     ......
    }.  
    .navigationBarTitle("") //this must be empty
    .navigationBarHidden(true)
    .navigationBarBackButtonHidden(true)
}

I tried multiple solutions, including UINavigationControllerDelegate and nothing seems to make the navigationBar permanently hidden. Until I tried KVO :)

So if you want a permanent solution, use this:

struct NoBarNavigationView<Content: View>: View {

    private let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        NavigationView {
            content
                .introspectNavigationController { (UINavigationController) in
                    NavigationControllerDelegate.shared.becomeDelegate(of: UINavigationController)
                }
        }
    }
}

class NavigationControllerDelegate: NSObject {

    static let shared = NavigationControllerDelegate()

    func becomeDelegate(of navigationController: UINavigationController) {
        navigationController.isNavigationBarHidden = true
        navigationController.navigationBar.isHidden = true
        navigationController.navigationBar.addObserver(self, forKeyPath: "alpha", options: .new, context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        // This is necessary to ensure the UINavigationBar remains hidden
        if let navigationBar = object as? UINavigationBar {
            navigationBar.isHidden = true
        }
    }

}

Happy coding!

EDIT: As pointed out in the comments, I am using:

import Introspect

GitHub link

To hide the NavigationBar specifically in your 3rd View . You have to remove .navigationBarTitle("View Three") and the bar gets hidden:

struct ContentViewThree: View {
    var body: some View {
        ZStack {
            Color.gray.edgesIgnoringSafeArea(.all)
            Text("View Three")
        }
        .navigationBarHidden(true)
        .navigationBarBackButtonHidden(true)
    }
}

Posting this for more visibility in dealing with SwiftUI NavigationBar not hiding, or still taking up space when it is hidden:

.navigationBarHidden(true)
.navigationBarTitle("", displayMode: .inline)
.edgesIgnoringSafeArea([.top, .bottom])

That sets a title (hack sometimes required for old swiftUI versions), hides the bar, but also tells the rendering engine to ignore any safe areas that reserve space for the navigation bar (presumptively).

You need to add .navigationBarHidden(true) on navigationView, or if you have NavigationLink you need to add on the Link

   NavigationLink("",
                               destination: Text("TEST"),
                               tag: linkValue,
                               selection: $linksNavigator.selection)
                    **.navigationBarHidden(true)**

Because you should add hidden properties to DetailView instead of NavigationLink,

 NavigationLink(destination: DetailView(mData: sportData)
                                .navigationBarTitle("")
                                .navigationBarHidden(true)
                                .navigationBarBackButtonHidden(true)
                
                ) {
                    Image("arrowRight3").resizable()
                    //.padding(5)
                    //.background(.red)
                       

In iOS 15 you can use a @State property to toggle the state.

@State private var hideNavigationbar: Bool = false

You switching the value in .onAppear {} to true. When you dismiss the view you call .onDisappear {} and set the property to false.

Now you can use it like so:

.navigationbarHidden(hideNavigationbar)

With iOS 15.5 and 15.6 .navigationBarHidden(true) simply doesn't work. Adding .navigationBarTitle("", displayMode: .inline) doesn't help either. It's obviously a bug in iOS 15.

It's fixed in iOS 16!

Tested with Xcode 14 Beta 5 Simulated iOS 15.5, iPhone w/ iOS 15.6 and Simulated iOS 16, the bug got fixed in iOS 16.

The latest hiding method, suitable for iOS15


.navigationBarHidden(true)
.ignoresSafeArea()


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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM