overriding UINavigationItem of a UIViewController broken for iOS16.

On overriding UINavigationItem of a UIViewController, the left and right UIBarButtonItems don't appear in iOS16 . The same code works for iOS16 and below.

In the snippet below if VC is presented the left bar items don't show up.

class VC:UIViewController {
  override var navigationItem: UINavigationItem {
    get {
      return NavItem()
    } set {
    }
  }
}

class NavItem: UINavigationItem {
  override var leftBarButtonItems: [UIBarButtonItem]? {
    get {
      let view2 = UIView.init(frame: CGRect.init(x: 3, y: 3, width: 40, height: 40))
      view2.backgroundColor = .gray
      return [UIBarButtonItem.init(customView: view2)]
    } set {
       
    }
  }
   
  override var titleView: UIView? {
    get {
      let view2 = UIView.init(frame: CGRect.init(x: 3, y: 3, width: 40, height: 40))
      view2.backgroundColor = .systemRed
      return view2
    } set {
       
    }
  }
}

It is not expected that you subclass UINavigationItem or override UIViewController.navigationItem and doing both have significant gotchas that you are running into. In general there is no guarantee that a framework will ever call the getters of a property.

For what you are doing, we would recommend instead that you use the UINavigationItem that UIViewController creates for you and setup your leftBarButtonItems and titleView inside of viewDidLoad or loadView.

What I'm saying is your overrides are not supported. UIViewController.navigationItem is expected to be used as is.

Hi @Rincewind, this seems to contradict the documentation, which says:

To ensure the navigation item is configured, you can either override this property and add code to create the bar button items when first accessed or create the items in your view controller's initialization code.

In my app, we load (once) a pre-built UINavigationItem from a nib via an outlet and then return it in an override of navigationItem. As of iOS 16 this is working fine and seems to be in compliance with the documentation. Should we worry that this will break at some point?

The documentation is wrong on this point.

That’s disconcerting. Shouldn’t the published documentation be considered as part of the contract for using this API? We now know of at least two apps that are relying on the “you can […] override this [navigationItem] property” behavior. The OP’s problem may be due to overriding leftBarButtonItems which isn’t mentioned in the docs one way or the other[1], but for the case of navigationItem it would be much appreciated if the documented behavior remained supported going forward.


[1] But in various cases, classes or method that don’t support subclassing or overriding are explicitly called out as such.

overriding UINavigationItem of a UIViewController broken for iOS16.
 
 
Q