仅在模态显示的视图控制器上隐藏状态栏

Posted

技术标签:

【中文标题】仅在模态显示的视图控制器上隐藏状态栏【英文标题】:Hide status bar only on modally presented view controller 【发布时间】:2017-11-14 04:32:11 【问题描述】:

我有一个视图控制器A,它在顶部显示状态栏。从那个视图控制器中,我想展示另一个隐藏状态栏的视图控制器B。为了实现这一点,我重写了该属性

override var prefersStatusBarHidden: Bool 
    return true

B。为了在状态栏(dis)出现时强制执行流畅的动画,我还覆盖了该属性

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation 
    return .slide

但是,当我现在从A 呈现视图控制器B 时,状态栏突然消失了,而A 仍然可见,就在动画模态转换开始之前。

我正在寻找一种方法来修复这种“跳跃状态栏”行为。理想情况下,我希望有一个干净的分离:

A显示状态栏 B不显示状态栏

这样,当我呈现B 时,状态栏就会被它覆盖。

由于状态栏似乎是一个不属于任何特定视图控制器的全局视图,因此可能很难实现这种行为。因此,如果无法复制这种确切的动画行为,我也会很高兴状态栏在视图控制器转换期间顺利滑出。我怎样才能做到这一点?

【问题讨论】:

【参考方案1】:

为了在过渡期间为状态栏设置动画,您可以在视图控制器 B 中执行以下操作:

var willAppear = false

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation 
    return .slide


override var prefersStatusBarHidden: Bool 
    return willAppear


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(true)
    willAppear = true
    UIView.animate(withDuration: 0.5) 
        self.setNeedsStatusBarAppearanceUpdate()
    

那么我想如果你想要在模态控制器被解除时产生相反的效果,你需要做相反的事情。

您可以将动画的持续时间调整为适合您的任何时间,但我不确定viewWillAppear 与实际完全呈现的模态控制器之间的持续时间有多一致。

编辑:

“相反”最终变成这样(在视图控制器 A 中):

var willAppear = false

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation 
    return .slide


override var prefersStatusBarHidden: Bool 
    return willAppear


override func viewWillDisappear(_ animated: Bool) 
    super.viewWillDisappear(animated)
    if let _ = presentedViewController as? B 
        willAppear = true
    


override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(true)
    if let _ = presentedViewController as? B 
        willAppear = false
        UIView.animate(withDuration: 0.5) 
            self.setNeedsStatusBarAppearanceUpdate()
        
    

我同意,对于我想很多人想要的东西来说,代码太多了。

【讨论】:

感谢您的回答。其中一半有效,另一半(关闭视图控制器时的“相反”)无效。您似乎需要向参与转换的 both 视图控制器添加代码,以便为状态栏获得平滑的滑入 滑出动画。稍后我将添加另一个答案来解释这种方法。真的很烦人,Apple 把它弄得如此复杂,并且没有自动为状态栏设置动画——我声称在 99% 的情况下,这将是开发人员想要的行为。 对不起,我应该更好地澄清“相反”!我认为这可能会发生。过渡回来似乎也有点棘手。我认为您可能需要使用viewWillDisappearviewWillAppear 并确保在设置标志之前移动到需要隐藏状态栏的视图控制器。我也会更新我的答案。

以上是关于仅在模态显示的视图控制器上隐藏状态栏的主要内容,如果未能解决你的问题,请参考以下文章

关闭 Modal ViewController 将父视图隐藏在状态栏后面

隐藏在模态视图中的状态栏(在全屏演示中)

状态栏在关闭模式视图后保持隐藏并在几秒钟后出现

在 iOS 9 的一个视图控制器上隐藏状态栏

隐藏/显示 PageViewController 中特定视图控制器的状态栏 [关闭]

关闭模态视图后的状态栏和导航栏问题