Установите цвет StatusBar для расширений в UIActivityViewController

Дана следующая ситуация:

Приложение iOS 8+ (в основном Swift). StatusBar имеет значение View controller-based status bar appearance. В приложении несколько UIActivityViewController используются для отображения параметров общего доступа.

Проблема: некоторые действия по совместному использованию имеют неправильные цвета строки состояния. Это расширения, установленные на устройстве, которые отображаются при использовании UIActivityViewController. Здесь: действия по обмену, такие как, например. Вотсап, Тамблер, Скайп.

Чего я хочу добиться: СтатусBarStyle по умолчанию для этого приложения — .LightContent, чтобы соответствовать локальному UIAppearance (подкрашивая базовый класс NavigationController). Удаленные полноэкранные контроллеры должны получить .Default StatusBarStyle, в то время как модальные диалоги должны сохранить текущий стиль (.LightContent).

Я проверил каждую возможную комбинацию, и теперь я застрял.

Код в контроллере основного представления (приложение с вкладками):

    override func preferredStatusBarStyle() -> UIStatusBarStyle {
        return .LightContent
    }

    override func prefersStatusBarHidden() -> Bool {
        return false
    }

    override func childViewControllerForStatusBarStyle() -> UIViewController? {
        guard let presentedViewController = presentedViewController else {
            return nil
        }

        switch presentedViewController {
        case is SLComposeViewController: // Social Sharing, e.g. Facebook, WhatsApp, Reminders etc.
            // let rawPresentationStyle = presentedViewController.modalPresentationStyle.rawValue
            // rawPresentationStyle == 17 (0x11) is undocumented Raw Value for SLComposeViewController dialogs
            return presentedViewController
        case is UIActivityViewController:
            // i.e. "More" Activity, UIActivityViewController internally uses presentViewController again to show "More" View
            // presentedViewController.modalPresentationStyle != presentedViewController.presentedViewController.modalPresentationStyle (e.g. .Popover to .OverCurrentContext)
            let presentedStyle = presentedViewController.presentedViewController?.modalPresentationStyle // UIActivity > presented
            if presentedStyle == .OverFullScreen {
                return presentedViewController
            }
        default:
            break
        }

        return nil // use local preferredStatusBarStyle
    }

Код работает нормально. Проверял правильность переключения на каждом этапе. Однако SLComposeViewController инициирует удаленный просмотр XPC: SLRemoteComposeViewController вместе с _UIRemoteView.

Оба не устанавливают .modalPresentationStyle, поэтому нет никакого способа получить это значение, чтобы решить, передать управление представленному ViewController или нет.

В общем, независимо от того, является ли XPC Remote View модальным (затемнение в текущем контексте) или полноэкранным, StatusBar становится .Default при возврате управления self.presentedViewController.

Я смог отследить его до XPC. modalPresentationStyle SLComposeViewController имеет недокументированный стиль 17 (0x11).

Кто-нибудь понял, как установить правильный StatusBar для совместного использования в социальных сетях вместе с UIActivityViewController?

Редактировать: я также пытался установить View controller-based status bar appearance на нет. С этой настройкой preferredStatusBarStyle и childViewControllerForStatusBarStyle: вообще не вызываются, согласно документации. Но в любом случае это не сработает, независимо от того, является ли строка состояния .LightContent или .Default. Либо удаленная активность Modal неверна, либо удаленная активность FullScreen. Конечно, удаленные представления XPC не находятся под контролем разработчика. Из того, что я узнал, у разработчиков расширений (Facebook, WhatsApp и т. д.) есть та же проблема, но наоборот: они не могут ни управлять панелью состояния, ни...

Я что-то пропустил?

Edit2: изменен заголовок, я также знаю о modalPresentationCapturesStatusBarAppearance.

Я нашел этот интересный пост в блоге от команды инженеров в Tumblr, датированный 2014 годом, у них также есть неустранимые проблемы с StatusBar при создании расширения общего доступа. См. http://engineering.tumblr.com/post/97658880154/what-we-learned-building-the-tumblr-ios-share — указывает на: http://openradar.appspot.com/radar?id=6397505050771456

Обходной путь

Не так далеко. Ни клавиши Info.plist, ни методы контроллера представления не работали, и мы даже не смогли получить дескриптор окна клавиатуры, как это обычно делают приложения с помощью частного API (Сэм Гиддинс чуть не сошел с ума, пытаясь. Спасибо. Сэм!). Мы надеемся найти способ сделать это в iOS 8.1.

Я тоже чуть не сошел с ума, пытаясь ;)


person Frederik Winkelsdorf    schedule 08.03.2016    source источник
comment
Единственный способ, которым я решил это в прошлом, - установить UIApplication.sharedApplication().statusBarStyle на светлый или темный в блоке завершения представления контроллера модального представления.   -  person ackerman91    schedule 08.03.2016
comment
Спасибо. Хм, попробовал это сейчас, при реализации выглядело знакомо;) Не сработало - кстати, установка .statusBarStyle напрямую устарела в iOS 9. Виновником является .presentedViewController. Как только я передаю ему контроль над StatusBar в childViewControllerForStatusBarStyle(), панель не работает с удаленными модальными окнами. Если я оставлю это, панель неверна с удаленными полноэкранными режимами. Это беспорядок .. Из того, что я узнал, разработчики расширения активности также не имеют контроля над StatusBar. Я собираюсь открыть тикет Radar, но это сложный вопрос для понимания поддержки .   -  person Frederik Winkelsdorf    schedule 08.03.2016