Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation Bar hide is not working in SwiftUI

Tags:

ios

swift

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)
    }
}

enter image description here

like image 841
Azhagusundaram Tamil Avatar asked Nov 25 '19 08:11

Azhagusundaram Tamil


2 Answers

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)
}
like image 55
Rohit Makwana Avatar answered Oct 27 '22 01:10

Rohit Makwana


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

like image 24
Miroslav Kuťák Avatar answered Oct 27 '22 02:10

Miroslav Kuťák