Search code examples
iosuinavigationcontrollerstatusbarios11

iOS 11 Hiding Status Bar pulls my Navigation Controller to the top of the screen


I'm building an application using a UINavigationController embedding a UIPageViewController. In one of the UIPageViewController UIViewControllers, I have a button to display a Photo Gallery, and when showing this modal Photo Gallery UIViewController, I'm hiding the status bar because the Photo Gallery is full screen :

self.present(self.photosViewController!, animated: true, completion: nil)

The problem is that when the transition occurs (the modal UIViewController fades in with a black background), I can see my UINavigationController move up by 20px to the top of the screen, where the Status Bar was.

The problems does not occur when I build on iOS 9.3 or 10.3 simulators, only on iOS 11.0 simulator.

Any way to prevent the IUNavigationController from moving up when hiding the Status Bar?


Solution

  • What I did is to subclass the UINavigationBar class and use it in my UINavigationController (in Storyboard, specify the custom class for the Navigation Bar, under the Navigation Controller) :

    class CustomUINavigationBar: UINavigationBar {
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            if (self.frame.origin.y == CGFloat(0)) {
                self.frame.origin.y = CGFloat(20)
            }
    
            for subView in self.subviews {
                if (subView.className == "_UIBarBackground") {
                    subView.frame.size.height = 64
                    subView.frame.origin.y = -20
                }
            }
        }
    
    }
    

    The className property comes from :

    extension NSObject {
        var className: String {
            return NSStringFromClass(type(of: self))
        }
    }