Fixed Height Navigation Bar On iOS 7

In iOS 7 Apple introduced new approach to status bar. It is now rendered above the navigation bar, effectively looking as a part of it. It required some efforts to adapt older applications to this new approach. If developer follows Apple suggestions and guidelines that's not really hard thing to figure out and adapt.

There is, however, an obscure and undocumented issue that might cause some headache. It happens when for some reason application needs to hide and show status bar on certain view controller. Drawer-styled side menu is a good example of the case when developer might need to do this.

It is easy to hide and show status bar:

[self setNeedsStatusBarAppearanceUpdate];

// ...

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

However, if status bar is hidden, iOS will eventually make navigation bar height smaller to compensate for status bar size. In some cases this may even affect other view controllers preseneted as modals. The mechanism of this behavior is described here:

UINavigationController will alter the height of its UINavigationBar to either 44 points or 64 points, depending on a rather strange and undocumented set of constraints. If the UINavigationController detects that the top of its view’s frame is visually contiguous with its UIWindow’s top, then it draws its navigation bar with a height of 64 points. If its view’s top is not contiguous with the UIWindow’s top (even if off by only one point), then it draws its navigation bar in the “traditional” way with a height of 44 points. This logic is performed by UINavigationController even if it is several children down inside the view controller hierarchy of your application.

To overcome this I have created a category for UINavigationBar which completely disables navigation bar resizing if fixedHeightWhenStatusBarHidden is set to YES. Feel free to use and don't forget star it on Github if you find it useful.

Vitaliy Ivanov Technical Director at Factorial Complexity