滚动时隐藏状态栏

Posted

技术标签:

【中文标题】滚动时隐藏状态栏【英文标题】:Hide status bar while scrolling 【发布时间】:2014-11-29 14:13:54 【问题描述】:

ios 8 增加了一个超酷的新功能:当用户滚动时隐藏导航栏。

这在viewDidload 中有一行:

navigationController?.hidesBarsOnSwipe = true

很酷,不是吗?

但是现在我有个小问题:导航栏隐藏的时候,状态栏还在,和内容重叠,很难看。

导航栏隐藏时如何使其隐藏?

【问题讨论】:

嘿,你有没有发现如何做到这一点?谢谢! 不,很遗憾...你能加 1 吗? 看看我的问题:***.com/questions/25870382/… 谢谢,但它是 obj c 解决方案,我对开发人员真的很陌生,也只懂 swift 语言。很难将其翻译成 swift 版本。你能帮我做这件事吗? 【参考方案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】:

我将这个答案基于this post 上的一些 cmets,这是推测。我不确定这是否可行,因为 Apple 没有为我们提供导航栏何时隐藏的任​​何直接方法或委托方法。

将 UINavigationBar 子类化为 NavigationBar。像这样向它的hidden 属性添加一个属性观察者:

var hidden: Bool
didSet
    UIApplication.sharedApplication().setStatusBarHidden(self.hidden, animation: .Slide)


然后,您想在主视图控制器中转到 viewDidLoad 方法,并将您的 self.navigationBar 属性(或 self.navigationController.navigationBar,不确定是哪一个)设置为新 NavigationBar 类的实例。

请注意,我现在无法对此进行测试,请告诉我如何/是否有效。

【讨论】:

它没有。我必须在哪里放置 var hidden 声明? self.navigationController.navigationBar 给我“UINavigationController 没有名为 navigationBar 的成员”。 self.navigationBar 给我“myTableViewController 没有名为 navigationBar 的成员” @jmcastel UINavigationController 没有导航栏吗? developer.apple.com/library/ios/documentation/Uikit/reference/…【参考方案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

我的视图控制器也有一个扩展,称为 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】:

好吧,我花了一整天的时间做这个,希望这可以帮助一些人。有一个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

【讨论】:

以上是关于滚动时隐藏状态栏的主要内容,如果未能解决你的问题,请参考以下文章

隐藏 NavBar 但显示带背景的状态栏

隐藏导航栏时隐藏状态栏 - SWIFT iOS8

如何隐藏应用状态栏

如何在swift中逐渐隐藏状态栏

隐藏导航栏时显示状态栏

导航栏隐藏XCode时状态栏更改色调颜色