仅在模态显示的视图控制器上隐藏状态栏
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% 的情况下,这将是开发人员想要的行为。 对不起,我应该更好地澄清“相反”!我认为这可能会发生。过渡回来似乎也有点棘手。我认为您可能需要使用viewWillDisappear
和viewWillAppear
并确保在设置标志之前移动到需要隐藏状态栏的视图控制器。我也会更新我的答案。以上是关于仅在模态显示的视图控制器上隐藏状态栏的主要内容,如果未能解决你的问题,请参考以下文章
关闭 Modal ViewController 将父视图隐藏在状态栏后面