Скрыть строку состояния при прокрутке
В iOS 8 добавлена супер новая крутая функция: скрытие панели навигации при прокрутке пользователя.
Это с одной строкой в viewDidload
:
navigationController?.hidesBarsOnSwipe = true
Прохладный, не так ли?
Но теперь у меня есть небольшая проблема: когда панель навигации скрыта, строка состояния все еще здесь и перекрывает содержимое, что является уродливым.
Что делать, чтобы скрыть его, когда панель навигации скрыта?
Ответы
Ответ 1
Переопределите следующие методы в 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
}
}
Обновите barsHidden
где-нибудь в коде и вызовите setNeedsStatusBarAppearanceUpdate()
Ответ 2
Это фиксированная проблема для Xcode 6.1
navigationController?.navigationBar.hidden = true
Ответ 3
Я основываю этот ответ на комментариях этот пост, которые являются предположениями. Я не уверен, что это будет работать, потому что Apple не дает нам никакого прямого способа или метода делегирования, когда скрывается панель навигации.
Подкласс UINavigationBar как NavigationBar. Добавьте свойство observer к свойству hidden
следующим образом:
var hidden: Bool{
didSet{
UIApplication.sharedApplication().setStatusBarHidden(self.hidden, animation: .Slide)
}
}
Затем вы хотите перейти к вашему методу viewDidLoad
в главном контроллере представления и установить для своего нового класса NavigationBar свой self.navigationBar
(или self.navigationController.navigationBar
, не уверенный).
Обратите внимание, что я не могу проверить это прямо сейчас, дайте мне знать, как это работает.
Ответ 4
Вы можете обнаружить прокрутки с помощью UISwipeGestureRecognizer
. Я использую его в UIWebView:
В viewDidLoad у меня есть:
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
У меня также есть расширение для моего диспетчера view, называемого WebViewViewController:
extension WebViewViewController {
override func prefersStatusBarHidden() -> Bool {
return hideStatusBar
}
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return UIStatusBarAnimation.Slide
}
}
На уровне класса в моем WebViewViewController у меня также есть:
var hideStatusBar = false
func didSwipe() {
hideStatusBar = true
}
Ответ 5
Хорошо, я весь день делал это, надеюсь, это помогает некоторым людям. Там a barHideOnSwipeGestureRecognizer
. Таким образом, вы можете создать прослушиватель для соответствующего UIPanGesture
, отметив, что если панель навигации скрыта, то ее начало y - -44.0; в противном случае это 0 (не 20, потому что мы спрятали строку состояния!).
В вашем представлении контроллер:
// 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
}