I'm trying to use the new feature added in iOS 8 - hiding the navigation bar while user is scrolling the table view (similar to what mobile Safari does). I'm setting the property hidesBarsOnSwipe
of UINavigationController
to YES
in viewDidAppear
method of UITableViewController
:
- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if([self.navigationController respondsToSelector:@selector(hidesBarsOnSwipe)]) { self.navigationController.hidesBarsOnSwipe = YES; } }
The navigation bar hides when the view is being scrolled. So far so good. But the status bar is still visible and my table view contents show through it, which looks ugly:
I tried setting edgesForExtendedLayout
to UIEdgeRectNone
or adjusting the contentInset
of the table view, but it didn't help. Is there any other solution to hide the status bar along with the navigation bar, or make it opaque?
Actually it is pretty easy to do. You just need to connect navigation isNavigationBarHidden property with status bar.
Objective-C
- (BOOL)prefersStatusBarHidden { return self.navigationController.isNavigationBarHidden; }
Swift <= 2.3
override func prefersStatusBarHidden() -> Bool { return navigationController?.navigationBarHidden ?? false }
Swift 3.0
override var prefersStatusBarHidden: Bool { return navigationController?.isNavigationBarHidden ?? false }
And be sure you have "View controller-based status bar appearance" = "YES" in your application .plist file.
Building off of anas' answer, I have a working solution (I'm assuming tableViewController
is your UITableViewController
instance):
In a UINavigationController
subclass (or also potentially from tableViewController
):
- (void)viewDidLoad { if ([self respondsToSelector:@selector(barHideOnSwipeGestureRecognizer)]) { // iOS 8+ self.hidesBarsOnSwipe = YES; [self.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)]; } } - (void)swipe:(UISwipeGestureRecognizer *)recognizer { BOOL shouldHideStatusBar = self.navigationController.navigationBar.frame.origin.y < 0; tableViewController.hideStatusBar = shouldHideStatusBar; [UIView animateWithDuration:0.2 animations:^{ [tableViewController setNeedsStatusBarAppearanceUpdate]; }]; }
In your tableViewController
:
@property(nonatomic, getter = shouldHideStatusBar) BOOL hideStatusBar; - (BOOL)prefersStatusBarHidden { return [self shouldHideStatusBar]; }
Let me know if this doesn't work for you. A few non-obvious things:
self.navigationController.navigationBar.frame.origin.y
was -44 (the negative height of the navigation bar) when hidden, and 20 (the height of the status bar) when visible. There was no in-between, even during animations, so a negative value == hidden and a nonnegative value == visible.UIViewController
within a UINavigationController
within a UITabBarController
, and it didn't work until I overrode prefersStatusBarHidden
on the UIViewController
.setNeedsStatusBarAppearanceUpdate
in an animation block.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With