Как использовать modalPresentationCapturesStatusBarAppearance = NO с пользовательским UIPresentationController?

У меня есть пользовательский UIPresentationController и переопределяет frameOfPresentedViewInContainerView для пользовательского представления viewController. Все отлично работает, кроме строки состояния.

Я не хочу, чтобы строка состояния вообще меняла внешний вид - она ​​должна оставаться такой, какой она выглядела раньше. Теперь документация Apple. Я должен быть в порядке, и строка состояния не должна меняться.

С этим кодом:

- (BOOL)prefersStatusBarHidden {
    NSLog(
        @"prefersStatusBarHidden was called %d %ld",
        self.modalPresentationCapturesStatusBarAppearance,
        (long)self.modalPresentationStyle
    );

    return YES;
}

Я вижу, что prefersStatusBarHidden вызывается, даже если modalPresentationCapturesStatusBarAppearance равно NO (отображается как 0), а modalPresentationStyle имеет значение UIModalPresentationCustom (отображается как 4).

Очевидно, именно поэтому строка состояния изменяется при представлении viewController.

Но почему?

Я думаю, что iOS считает, что viewController представлен в полноэкранном режиме, хотя это не так.

Я обнаружил свойство UIPresentationController mustPresentInFullscreen - по умолчанию оно возвращает YES. Возврат NO вообще не помогает, так что я не понимаю, что вообще делает это свойство... Это буквально не действует. То же самое относится и к свойству presentationStyle - я не вижу никакого эффекта при его изменении. Я бы ожидал, что свойство presentationStyle будет "перенаправлено" в свойство viewControllers modalPresentationStyle, но оно остается в UIModalPresentationCustom, что должно быть в первую очередь для инициирования пользовательской презентации.

Итак, мои вопросы: кто-нибудь знает, как просто сохранить строку состояния, как это делается с помощью пользовательского UIPresentationController - и может ли кто-нибудь объяснить свойства shouldPresentInFullscreen и presentationStyle?

Спасибо!:)

1 ответ

Попробуйте реализовать childViewControllerForStatusBarStyle: и вернуть nil для него в классе, вызывающем ваш UIPresentationController, обычно UINavigationController.

Это то, что я делаю в Swift, когда я не хочу, чтобы детский ВК мешал моему мудро выбранному стилю строки состояния:

override func childViewControllerForStatusBarStyle() -> UIViewController? {
    return nil // ignore childs and let this Navigation Controller handle the StatusBar style
}

override func preferredStatusBarStyle() -> UIStatusBarStyle {
    return .LightContent // or .Default depending on your Style
}

Это требует iOS8 и новее и может использоваться только если вы устанавливаете ключ UIViewControllerBasedStatusBarAppearance в вашем Info.plist в YES,

Бонус: если это не помогает вызывающему, используйте его в показанном контроллере. Я проверил свои проекты, в одном из них он также находится в NavigationController, который отображается как PopOver и работает нормально на сегодняшний день.