Subview in UINavigationBar

In my Application I am adding a UIView as a subView to the UINavigationBar.


let containerView = UIView()

containerView.frame = CGRect(x: 0, y: -(statusBarHeight), width: UIScreen.main.bounds.width, height: frame.height + statusBarHeight)

containerView.clipsToBounds = true

insertSubview(containerView, at: 0)


On iOS 10 the UIView will be placed under the barbuttonitems like I want it to be.

On iOS 11 will always be placed at the very top and therefore is hiding the titleLabel and barbuttonitem.


Any ideas?

It appears that UINavigationBar may have a custom implementation of addSubview or insertSubview that preserves it's desired view hierarchy and inserts your custom view at the end.


There is a _UIBarBackground at index 0. It holds the UIVisualEffectViews if you were to make the nav bar translucent. The below code is basically inserting the custom subview into _UIBarBackground as it's subview at index 0.


This appears to work now with iOS 11, but cannot be guaranteed to work in the future, since it depends on one of UINavigationBar's view hierarchy, which is not something you control.


        if let nbar = navigationController?.navigationBar, nbar.subviews.count > 0 {
            let v = UIView(frame: nbar.subviews[0].bounds)
            v.backgroundColor = UIColor.red
            v.translatesAutoresizingMaskIntoConstraints = true
            v.autoresizingMask = [.flexibleHeight, .flexibleWidth]
            nbar.subviews[0].insertSubview(v, at: 0)
        }

has anyone found a better solution?

I am having a similar issue with UITableViewController and insertSubview at index 0 behaving differently than iOS 9 or iOS 10. It is placing my background at the top of the subviews and not behind in iOS 11, blocking my tableview.


https://forums.developer.apple.com/message/259680#259680

You could add your subview to the nav bar with a smaller frame, and just make sure clipping is off.

Subview in UINavigationBar
 
 
Q