Hiding Navigation Bar and Status Bar with Animation on iOS
In iOS 7 Apple changed the way a status bar is laid out in the view hierarchy. Mainly, UINavigationController's
navigationBar
is pinned to the status bar, so when the status bar is hidden the position of the navigation bar changes. It means that when we want to simultaneously hide both these elements, we have to perform the operations in the correct order.
Here's how we can do that:
@interface ViewController()
@property (nonatomic, getter = isStatusBarHidden) BOOL statusBarHidden;
@end
@implementation ViewController
#pragma mark - UIViewController
- (BOOL)prefersStatusBarHidden
{
return self.isStatusBarHidden;
}
#pragma mark - Public
- (void)toggleNavigationBarAndStatusBarVisibility
{
BOOL willShow = self.navigationController.navigationBarHidden;
if (willShow) {
[self toggleStatusBarHiddenWithAppearanceUpdate:NO];
[self toggleNavigationBarHiddenAnimated:YES];
} else {
[self toggleNavigationBarHiddenAnimated:YES];
[self toggleStatusBarHiddenWithAppearanceUpdate:YES];
}
}
#pragma mark - Private
- (void)toggleStatusBarHiddenWithAppearanceUpdate:(BOOL)updateAppearance
{
self.statusBarHidden = !self.isStatusBarHidden;
if (updateAppearance) {
[UIView animateWithDuration:UINavigationControllerHideShowBarDuration animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
}
}
- (void)toggleNavigationBarHiddenAnimated:(BOOL)animated
{
[self.navigationController
setNavigationBarHidden:!self.navigationController.navigationBarHidden
animated:animated];
}
@end
And here it is in action. We can also change the default status bar animation by implementing preferredStatusBarUpdateAnimation
.