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 p
After much struggle, I was finally able to solve this.
Add the following code to the UIViewController's viewDidLoad function:
// Create a solid color background for the status bar (in Swift Code)
let statusFrame = CGRectMake(0.0, 0, self.view.bounds.size.width,
UIApplication.sharedApplication().statusBarFrame.size.height)var statusBar = UIView(frame: statusFrame)
statusBar.backgroundColor = UIColor.whiteColor()
self.view.addSubview(statusBar)
What you are doing is creating a solid bar right beneath the navigation bar. As the navigation bar moves up, the solid bar move up too and right behind the status bar.
The only problem is that when you rotate the screen side ways, the white bar still there even though the status bar disappears.
Okay I spent all day doing this, hopefully this helps some people out. There's a barHideOnSwipeGestureRecognizer
. So you could make a listener for the corresponding UIPanGesture
, noting that if the navigation bar is hidden then its y origin is -44.0; otherwise, it's 0 (not 20 because we hid the status bar!).
In your view controller (swift 2):
// Declare at beginning
var curFramePosition: Double!
var showStatusBar: Bool = true
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
override func viewDidLoad(){
self.navigationController?.hidesBarsOnSwipe = true
curFramePosition = 0.0 // Not hidden
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
}
func didSwipe(swipe: UIPanGestureRecognizer){
// Visible to hidden
if curFramePosition == 0 && self.navigationController?.navigationBar.frame.origin.y == -44 {
curFramePosition = -44
showStatusBar = false
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
// Hidden to visible
else if curFramePosition == -44 && self.navigationController?.navigationBar.frame.origin.y == 0 {
curFramePosition = 0
showStatusBar = true
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
}
override func prefersStatusBarHidden() -> Bool {
if showStatusBar{
return false
}
return true
}
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.
You need to connect navigation isNavigationBarHidden property with status bar.
return self.navigationController.isNavigationBarHidden;
The answer from @iOSergey works perfect!
Here is the solution in Swift 1.2. Add the following code to the views .swift file:
override func prefersStatusBarHidden() -> Bool {
return self.navigationController!.navigationBarHidden as Bool
}
That new property comes with its barHideOnSwipeGestureRecognizer
.
From the UINavigationController Class Reference:
You can make changes to the gesture recognizer as needed but must not change its delegate and you must not remove the default target object and action that come configured with it. Do not try to replace this gesture recognizer by overriding the property.
But you can add a target:
[self.navigationController setHidesBarsOnSwipe:YES];
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipeGesture:)];
... and do whatever you want in the callback:
- (void)swipeGesture:(UIPanGestureRecognizer*)gesture
{
// Tweak the status bar
}
You might have to manually switch on the gesture states, figure out when to hide/show the status bar, etc. Hope that helps!