Остановить оверлей UIWindow от управления строкой состояния - PullRequest
0 голосов
/ 21 января 2020

Я создаю временное окно UIWindow поверх главного окна, чтобы показать небольшой объем данных, наложенных на остальную часть моего приложения. Эта информация никоим образом не должна влиять на строку состояния. Обратите внимание, что оверлейное окно может быть запущено из контекста контроллера без представления, это означает, что текущий контроллер представления в верхней части стека главного окна может не знать о существовании оверлейного окна.

К сожалению, как только я выполняю overlayWindow.isHidden = false, он передает управление строкой состояния (ее стиль и скрытность) контроллеру представления root моего оверлейного окна, и я не могу понять, как его остановить.

В качестве альтернативы, я мог бы просто «запомнить» предыдущее состояние строки состояния и сделать так, чтобы мой оверлей root просматривал вывод контроллера, но, похоже, нет хорошего способа узнать текущее состояние и видимость строки состояния в iOS 13, по крайней мере, которая учитывает модально представленные контроллеры представления, использующие новый эффект листа.

Как сделать так, чтобы мое оверлейное окно UIWindow надежно не влияло на строку состояния?

Редактировать: Я подготовил небольшой тестовый пример: https://github.com/Aquilosion/TestWindowView

Тестовый пример показывает Контроллер представления, который меняет внешний вид строки состояния каждую секунду. Вы можете снова открыть тот же контроллер представления в модальном режиме, и, несмотря на то, что он также запрашивает изменения строки состояния, iOS правильно блокирует строку состояния белым, потому что контроллер представления никогда не достигает ее в режиме листа. При открытии оверлея окна в настоящее время всегда отображается черная строка состояния, независимо от того, представлен модал или нет. Я пытаюсь установить дочернюю строку состояния в качестве root главного окна просмотра дочерней строки контроллера. В идеале iOS будет учитывать это и продолжать изменять стиль строки состояния, пока наложенное окно будет видимым.

1 Ответ

0 голосов
/ 21 января 2020

Вы можете переопределить свойство childForStatusBarStyle контроллера представления root оверлейного окна.

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

Я не уверен, что это поможет, учитывая, что контроллеры будут в разных windows, но стоит попробовать.

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]
    }
...