Empty space in navigation bar with titleView after updating on iOS 16

When I create even the simplest titleView and add it to the navigationItem I see an additional space on the left before the titleView. I'm attaching a screenshot from iPhone 13 Pro Max - on the left is iOS 16 and on the right is iOS 15

The code is:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .lightGray

        let titleViewWidth = UIScreen.main.bounds.width
        let titleView = UIView(frame: CGRect(x: 0, y: 0, width: titleViewWidth, height: 40))
        titleView.backgroundColor = .red
        navigationItem.titleView = titleView
}

In the view hierarchy I see the following

iOS 16

_UINavigationBarContentView

<_UINavigationBarTitleControl: 0x7f794e9079b0; frame = (20 2; 390 40); layer = <CALayer: 0x6000004c7960>> <_UITAMICAdaptorView: 0x7f794df08e40; frame = (0 0; 390 40); autoresizesSubviews = NO; layer = <CALayer: 0x6000004d9aa0>>

iOS 15

<_UINavigationBarContentView: 0x7f8294f0c620; frame = (0 0; 428 44); layer = <CALayer: 0x600001cb0020>> layout=0x7f82965113c0 <_UITAMICAdaptorView: 0x7f829651b940; frame = (12 2; 404 40); autoresizesSubviews = NO; layer = <CALayer: 0x600001ca82a0>>

So there is difference in 8 pointsfrom both sides (16 points in total) on iOS 16 and I don't know how to overcome this

I see you are deriving the width from UIScreen.main.bounds.width—what is this value returning on iOS 15 vs. iOS 16? (in other words, what is the actual value of titleViewWidth)?

On another note, you should not use the UIScreen's width to determine this, and you shouldn't be using UIScreen.main as it is deprecated. I would instead recommend using the width of the view controller's view, and in -viewWillTransitionToSize:withTransitionCoordinator:, update the width based on the new width.

It is not related to the width provided, I can simply hardcode another big enough value and have the same result:

    override func viewDidLoad() {         super.viewDidLoad()

        navigationItem.titleView = UIView(frame: CGRect(x: 0, y: 0, width: 404, height: 40))     }

This will result in navigationItem.titleView's frame:

iOS 15 iPhone 13 Pro Max <UIView: 0x7fb28c10b610; frame = (0 0; 404 40)>

iOS 16: iPhone 13 Pro Max <UIView: 0x7fe53ef1c3f0; frame = (0 0; 388 40)>

We have the same issue with simple hardcoded width value without using UIScreen.main.bounds.width:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.titleView =  UIView(frame: CGRect(x: 0, y: 0, width: 404, height: 40)) 
}

The frame of the navigationItem.titleView:

iOS 15: iPhone 13 Pro Max: <UIView: 0x7f85fda14d10; frame = (0 0; 404 40);>

iOS 16: iPhone 13 Pro Max: <UIView: 0x7f7894f157e0; frame = (0 0; 388 40);>

The result is the same as in the screenshot in the original question

Empty space in navigation bar with titleView after updating on iOS 16
 
 
Q