停止覆盖UIWindow控制状态栏

问题描述 投票:0回答:2

我正在主窗口顶部创建一个临时 UIWindow,以显示覆盖在应用程序其余部分上的一些少量数据。此信息不应以任何方式影响状态栏。请注意,覆盖窗口可以从非视图控制器上下文启动,这意味着主窗口堆栈顶部的当前视图控制器可能不知道覆盖窗口的存在。

不幸的是,一旦我这样做了

overlayWindow.isHidden = false
,它就会将对状态栏的控制(其样式以及是否隐藏)转移到我的覆盖窗口的根视图控制器,而我不知道如何停止它。

或者,我可以“记住”状态栏的先前状态,并让我的覆盖根视图控制器输出这些状态,但似乎没有一个好的方法来找出状态栏的当前状态和可见性iOS 13,至少考虑到使用新的工作表效果以模态方式呈现的视图控制器。

如何让我的覆盖 UIWindow 可靠地不影响状态栏?


编辑:我准备了一个小测试用例:https://github.com/Aquilosion/TestWindowView

测试用例显示了一个视图控制器,它每秒都会更改其状态栏外观。您可以在模式中再次打开相同的视图控制器,尽管它也请求状态栏更改,但 iOS 正确地将状态栏锁定为白色,因为视图控制器永远不会在工作表模式下到达它。当前打开窗口覆盖层总是显示黑色状态栏,无论是否显示模式。我尝试将状态栏子项设置为主窗口的根视图控制器的状态栏子项。理想情况下,iOS 会尊重这一点,并在覆盖窗口可见时继续更改状态栏样式。

ios swift uiwindow
2个回答
0
投票

您可以覆盖覆盖窗口的根视图控制器的属性

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()
}

考虑到控制器将位于不同的窗口中,我不确定这会有帮助,但值得一试。

enter image description here

我让你的案例成功了,只需更新代码:

private func updateStyle() {
    styleIndex += 1

    setNeedsStatusBarAppearanceUpdate()
    overlayWindow?.rootViewController?.setNeedsStatusBarAppearanceUpdate()
}

将其添加到 MainViewController:

required init?(coder: NSCoder) {
     super.init(coder: coder)

     modalPresentationCapturesStatusBarAppearance = true
 }

enter image description here

override var preferredStatusBarStyle: UIStatusBarStyle {
        if self.presentingViewController != nil {
            return .lightContent
        }
        return Self.styles[styleIndex % Self.styles.count]
    }

0
投票

我遇到了同样的问题并想分享我的解决方案,尽管我确实认为通常这种覆盖窗口的方法并不是 Apple/UIKit 希望我们做的(分层子视图控制器/模态呈现的视图控制器似乎更可取)。

但是我确实想要这个,因为我有一种弹出菜单,我真的想遍历所有内容,包括键盘输入附件视图,所以这是我的解决方案:

当从视图控制器呈现窗口时,您可以从视图控制器的窗口获取当前状态栏样式:

self.view.window?.windowScene?.statusBarManager?.statusBarStyle

然后通过设置一些变量将该样式赋予窗口的根视图控制器,然后在

override var preferredStatusBarStyle: UIStatusBarStyle
中使用它。

这将使状态栏样式与其呈现时保持一致。

© www.soinside.com 2019 - 2024. All rights reserved.