我正在主窗口顶部创建一个临时 UIWindow,以显示覆盖在应用程序其余部分上的一些少量数据。此信息不应以任何方式影响状态栏。请注意,覆盖窗口可以从非 View Controller 上下文启动,这意味着主窗口堆栈顶部的当前 View Controller 可能不知道覆盖窗口的存在。
不幸的是,一旦我这样做了overlayWindow.isHidden = false
,它将状态栏的控制(其样式以及是否隐藏)转移到我的覆盖窗口的 Root View Controller ,并且我不知道如何停止它。
或者,我可以“记住”状态栏的先前状态,并让我的覆盖 Root View Controller 输出这些状态,但似乎没有一个好的方法来找出当前状态和状态的可见性iOS 13 中的 bar,至少考虑到使用新的工作表效果以模态方式呈现的 View Controller 。
如何让我的覆盖 UIWindow 可靠地不影响状态栏?
<小时/>编辑:我准备了一个小测试用例:https://github.com/Aquilosion/TestWindowView
测试用例显示了一个 View Controller ,它每秒都会更改其状态栏外观。您可以在模式中再次打开相同的 View Controller ,尽管它也请求状态栏更改,但 iOS 正确地将状态栏锁定为白色,因为 View Controller 永远不会在工作表模式下到达它。当前打开窗口覆盖层总是显示黑色状态栏,无论是否显示模式。我尝试将状态栏子项设置为主窗口的 Root View Controller 的状态栏子项。理想情况下,iOS 会尊重这一点,并在覆盖窗口可见时继续更改状态栏样式。
最佳答案
您可以覆盖覆盖窗口的 Root View Controller 的属性childForStatusBarStyle
。
class YourRootController { // root of the overlay window
var controllerToInheritStatusAttributesFrom: UIViewController?
override var childForStatusBarStyle: UIViewController? {
return controllerToInheritStatusAttributesFrom
}
}
// Call this from any place of the app, where you show the overlay window
if let controller = overlayWindow.rootViewController as? YourViewController {
controller.controllerToInheritStatusAttributesFrom = // needed controller, which lies underneath
controller.setNeedsStatusBarAppearanceUpdate()
}
考虑到 Controller 将位于不同的窗口中,我不确定这是否有帮助,但值得一试。
我让你的案例成功了,只需更新代码:
private func updateStyle() {
styleIndex += 1
setNeedsStatusBarAppearanceUpdate()
overlayWindow?.rootViewController?.setNeedsStatusBarAppearanceUpdate()
}
将其添加到 MainViewController:
required init?(coder: NSCoder) {
super.init(coder: coder)
modalPresentationCapturesStatusBarAppearance = true
}
override var preferredStatusBarStyle: UIStatusBarStyle {
if self.presentingViewController != nil {
return .lightContent
}
return Self.styles[styleIndex % Self.styles.count]
}
关于ios - 停止覆盖 UIWindow 控制状态栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59837705/