Navigation Bar is not hidden when using UIHostingController

Nicolò Pasini
3 min readJul 26, 2022

--

I was creating the layout of a page inserting a SwiftUI component inside a UIKit ViewController when I noticed an unexpected Navigation Bar being visible.

Are you in the same situation? Here is what you have to do in order to hide it.

View Configuration

Let’s start with how the UI components were composed at the moment I noticed the issue. I have a MyViewController which is embedded in a UINavigationController

MyViewController contains:

  1. Container View: an empty View pinned to the Safe Area on leading, trailing, top and bottom constraints with no space;
  2. Yellow View: of course the yellow colored one, pinned to the Safe Area on leading, trailing and top constraints with zero space and with a fixed height of 120.

I have set the Navigation Bar as hidden in the UINavigationController:

When the MyViewController is loaded, I insert a SwiftUI View inside the container using an UIHostingController as showed here:

Running the App at this point will cause the Yellow View to be displayed with a margin from the top of the screen

The reason is that there is an extra 44 space between the Safe Area top margin and the top of Yellow View which corresponds exactly to the height of the Navigation Bar.

And now some… magic

Let’s do an experiment: in the viewDidLoad method of the ViewController substitute the SwiftUI View declared as:

let childController = UIHostingController( 
rootView: Text("Title")
)

with a UIKit ViewController:

let childController = UIViewController()

Can you gess what happens when you run the app?

Exactly, the Yellow View is displayed in the correct position, it is correctly pinned to the Safe Area top constraint and there is not any margin due to the Navigation Bar.

The solution

In order to solve the issue I have tried to set (again) the navigation bar to hidden in multiple places, but the only one making the app working correctly with the SwiftUI View is the viewDidAppear method:

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.setNavigationBarHidden(true, animated: false)
}

Doing this will display the Yellow View in the correct position.

Here is a link to a GitHub repository where you can find the code

--

--