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

У меня есть настраиваемый UIPresentationController, и он переопределяет frameOfPresentationViewInContainerView для настраиваемой презентации viewController. Все работает нормально, кроме статусной строки.

Я вообще не хочу, чтобы строка состояния меняла внешний вид - она ​​должна оставаться такой, какой она была раньше. Теперь документация Apple: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/occ/instp/UIViewController/modalPresentationCapturesStatusBarAppeferencerer говорит, что если modalPresentationStyle ORModalPresentationStyle не является UIModalPresentationStyle, то это UIModalPresentationStyle. Я должен быть в порядке, и строка состояния не должна меняться.

С помощью этого кода:

- (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 shouldPresentInFullscreen - по умолчанию оно возвращает YES. Возвращение NO совершенно не помогает, поэтому я даже не понимаю, что это свойство вообще делает ... Это буквально не имеет никакого эффекта. То же касается и свойства presentationStyle - я не вижу никакого эффекта при его изменении. Я ожидал, что свойство presentationStyle будет «перенаправлено» на свойство viewControllers modalPresentationStyle, но оно останется в UIModalPresentationCustom, что должно быть в первую очередь для инициирования настраиваемой презентации.

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

Спасибо! :)


person Vogel Vogel    schedule 27.07.2015    source источник
comment
Вы когда-нибудь разбирались с этим? Я также пытаюсь заставить UIPresentationController не отображать полноэкранный режим (на самом деле я хочу иметь возможность взаимодействовать с некоторыми базовыми элементами представления, например, с панелью вкладок). Я не могу понять, как заставить его предоставить мне PresentingViewController, который не является корневым контроллером представления окна.   -  person Charles A.    schedule 20.10.2015
comment
Нет, к сожалению, я так и не понял :(   -  person Vogel Vogel    schedule 24.10.2015
comment
Похоже, это было исправлено в iOS 10. Я придумал хакерское решение для iOS 9 здесь: stackoverflow.com/questions/34819013/   -  person Brian Nickel♦    schedule 12.07.2017


Ответы (1)


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

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

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.

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

person Frederik Winkelsdorf    schedule 04.03.2016
comment
Это на самом деле не отвечает на вопрос, я имею в виду, что в целом вы хотите, чтобы UIPresentationController можно было повторно использовать, не требуя, чтобы что-то было реализовано во всех представленных им контроллерах представления. И реализация чего-либо в представляющем контроллере представления вместо представленного ничего не делает, вот в чем был вопрос ... Но да, вы правы насчет бонуса, в настоящее время это единственный способ сделать это. - person Vogel Vogel; 09.03.2016
comment
@TedBuckland Вы правы, извините, что я не ответил на ваш вопрос, почему это вообще происходит. Честно говоря: я не могу ответить на эту часть вопроса, просто покажите, как я знаю, как обойти проблему. Очевидно, что обработка строки состояния в iOS в некоторых ситуациях неверна. В этом нет необходимости, вероятно, лучше всего для открытия билета радара. У меня есть сообщение об этой проблеме с UIActivityViewController, которое на данный момент не может быть исправлено: stackoverflow.com/questions/35874582/. - person Frederik Winkelsdorf; 10.03.2016