Adjust Navigation bar position and size

I have a custom UIPresentationController that within frameOfPresentedViewInContainerView returns a frame which is half of the screen size starting at the middle of the screen.

I have a bar button that will adjust the frame of the presented view to be full screen.

By default when presenting a UINavigationController modally, the Navigation Bar frame will be positioned below the status bar, with a background view that is 20 points taller, positioned 20 points above the navbar itself to underlap the statusbar (to make the background color of that match the navbar - practically making the navbar height 64 points).

But when the Navigation Controller is not positioned at the top, it won't add the extra 20 points to the background. This is fine at initial presentation, but when tapping the button to maximize the view, the navigation bar itself underlaps the statusbar.


I initially fixed this by changing the height of the navigation bar itself to 64 points, instead of relying on the background to underlap the status bar. But the documentation of UINavigationController states that you shouldn't do that:


It is permissible to customize the navigation bar’s appearance-related properties but you must never change its

frame
,
bounds
, or
alpha
values directly


I tried setting the delegate of the navigation bar, and returning .TopAttached as the UIBarPosition in positionForBar, but the background of the navigation bar stays the same and I can't get it to call the delegate method again, even after trying various ways to trigger display or layout.

Answered by Dex in 104951022

Did you try setting the navigation bar's hidden property to true and then back to false?

Accepted Answer

Did you try setting the navigation bar's hidden property to true and then back to false?

That's crazy. Setting it via the navigationController's navigationBarHidden property works:


    func adjustToFullScreen() {
        if let presentedView = presentedView(), containerView = self.containerView {
            UIView.animateWithDuration(0.8, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .CurveEaseInOut, animations: { () -> Void in
                presentedView.frame = containerView.frame
               
                if let navController = self.presentedViewController as? UINavigationController {
                    self.isMaximized = true
                   
                    navController.setNeedsStatusBarAppearanceUpdate()
                   
                    // Force the navigation bar to update its size
                    navController.navigationBarHidden = true
                    navController.navigationBarHidden = false
                }
                }, completion: nil)
        }
    }

Yea, the navigation controller recalculates the navigation bar's position when it is shown, which is why this works (and only works via the navigation controller variant – if you just hide the navigation bar itself there is no such calculation done).

Adjust Navigation bar position and size
 
 
Q