问题
iOS 8 adds a super new cool feature: hiding the navigation bar when user is scrolling.
This with a single line in viewDidload :
navigationController?.hidesBarsOnSwipe = true
Cool, isn't it?
But now I have a little problem: when the navigation bar is hidden, the status bar is still here and overlaps content, which is ugly.
What should I do to make it hidden when the navigation bar is hidden?
回答1:
Override the following methods on UIViewController:
extension MyViewController {
override func prefersStatusBarHidden() -> Bool {
return barsHidden // this is a custom property
}
// Override only if you want a different animation than the default
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .slide
}
}
Update barsHidden somewhere in the code and call
setNeedsStatusBarAppearanceUpdate()
回答2:
This is fixed problem for in Xcode 6.1
navigationController?.navigationBar.hidden = true
回答3:
I am basing this answer on some comments on this post, which are speculation. I am not sure if this will work, because Apple does not give us any direct way or delegate method for when the navigation bar hides.
Subclass UINavigationBar as NavigationBar. Add a property observer to its hidden property like so:
var hidden: Bool{
didSet{
UIApplication.sharedApplication().setStatusBarHidden(self.hidden, animation: .Slide)
}
}
You want to then go to your viewDidLoad method in your main view controller, and set your self.navigationBar property (or self.navigationController.navigationBar, not sure which one) to an instance of your new NavigationBar class.
Note that I cannot test this right now, let me know how/if this works.
回答4:
You could detect swipes by using UISwipeGestureRecognizer. I'm using it on UIWebView:
In viewDidLoad I have:
let swipeUp = UISwipeGestureRecognizer(target: self, action: "didSwipe")
let swipeDown = UISwipeGestureRecognizer(target: self, action: "didSwipe")
swipeUp.direction = UISwipeGestureRecognizerDirection.Up
swipeDown.direction = UISwipeGestureRecognizerDirection.Down
webView.addGestureRecognizer(swipeUp)
webView.addGestureRecognizer(swipeDown)
navigationController?.hidesBarsOnSwipe = true
I also have an extension to my viewcontroller, called WebViewViewController:
extension WebViewViewController {
override func prefersStatusBarHidden() -> Bool {
return hideStatusBar
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return UIStatusBarAnimation.Slide
}
}
On a class level in my WebViewViewController I also have:
var hideStatusBar = false
func didSwipe() {
hideStatusBar = true
}
回答5:
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:
// 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
}
来源:https://stackoverflow.com/questions/26197260/hide-status-bar-while-scrolling