Search code examples
swiftswiftuiuikit

SwiftUI hide navigation bar of UIKit UINavigationController(rootViewController: _)


I have a SwiftUI view:

struct Content View: View {
  var body: some View {
    Text("Content view")
  }
}

And I used menu which created with UIKit. And there my view should be UIViewController or UINavigationController. For show my swiftUI view I setted my view inside UINavigationController:

let navigationController = UIHostingController(rootView: Content()).inNavigation()

// inNavigation()
extension UIViewController{
    func inNavigation() -> UIViewController {
        let vc = self
        let navigationController = UINavigationController(rootViewController: self)
        vc.navigationController?.navigationBar.isHidden = true
        vc.navigationController?.setNavigationBarHidden(true, animated: true)
        vc.navigationController?.isNavigationBarHidden = true
        vc.navigationController?.isToolbarHidden = true
        vc.navigationController?.setToolbarHidden(true, animated: true)
        vc.navigationController?.accessibilityFrame = .zero
        
        navigationController.navigationController?.navigationBar.isHidden = true
        navigationController.navigationController?.setNavigationBarHidden(true, animated: true)
        navigationController.navigationController?.isNavigationBarHidden = true
        navigationController.navigationController?.isToolbarHidden = true
        navigationController.navigationController?.setToolbarHidden(true, animated: true)
        navigationController.accessibilityFrame = .zero
        return navigationController
    }
}

I tried to hide navigationBar. But it still showing:

enter image description here


Solution

  • The UINavigationController should be in view hierarchy so that could have effect.

    Here is worked variant, assuming you inject it into window in SceneDelegate (tested with Xcode 11.4 / iOS 13.4)

    extension UIViewController{
        func inNavigation() -> UIViewController {
            let navigationController = UINavigationController(rootViewController: self)
            DispatchQueue.main.async {
                navigationController.isNavigationBarHidden = true
            }
            return navigationController
        }
    }