IOS: стиль строки состояния по умолчанию с UIViewControllerBasedStatusBarAppearance ДА
Есть ли способ установить стиль строки состояния по умолчанию при сохранении UIViewControllerBasedStatusBarAppearance
?
Вот проблема, с которой я имею дело:
Почти все приложение должно использовать UIStatusBarStyle.LightContent
, поскольку панель навигации имеет темный фон. Первоначально UIViewControllerBasedStatusBarAppearance
был отключен, и в строке Info.plist
было установлено следующее: в строке состояния статуса текста:
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
Это работало очень хорошо, пока я не узнал, что эта строка состояния .LightContent
показана даже для некоторых расширений общего доступа, таких как Facebook Messenger, что делает ее нечитаемой:
![Стиль отображения состояния подсветки в Facebook Messenger]()
Это можно решить, используя UIViewControllerBasedStatusBarAppearance
, но тогда мне нужно будет добавить следующий метод ко всем контроллерам представлений, которые я хочу избежать, поскольку приложение достаточно велико.
Кроме того, для одного экрана приложения, имеющего светлый навигационный фон, я переключился на темную навигационную панель с помощью UIApplication.sharedApplication().setStatusBarStyle()
, но этот метод устарел в iOS 9.
Есть идеи, как это решить? Swizzling?
Ответы
Ответ 1
Решение
Самый простой и самый чистый способ добиться этого - добавить следующую строку в метод AppDelegate
application:willFinishLaunchingWithOptions
:
UINavigationBar.appearance().barStyle = .Black
Это приведет к тому, что .LightContent
будет использоваться в качестве стиля строки состояния по умолчанию для приложения, пока ваше приложение использует UINavigationController
.
Не забудьте сохранить следующий параметр в приложении Info.plist
, если вы хотите использовать стиль строки .LightContent
в строке состояния во время запуска для экрана заставки:
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
TL; DR
Моя текущая настройка, которая очень похожа на многие другие приложения, использует UITabBarController
как самый верхний контроллер с стеком UINavigationController
для каждой вкладки.
UINavigationController
заботится о стиле строки состояния (как следует) и не вызывать preferredStatusBarStyle()
на своих дочерних контроллерах. Таким образом, реализация подклассического решения, предложенного параметром, не работает в моем случае.
Дальнейшее подклассирование пользовательского подкласса UINavigationController
Я использую не будет также чистым решением.
Теперь, когда приложение UIViewControllerBasedStatusBarAppearance
включено и исправлено стиль строки состояния повсюду в самом приложении, SFSafariViewController
и расширение общего доступа, такое как Messages, Mail и т.д., также используйте правильный стиль строки состояния (.Default
).
Единственное исключение, в котором не используется правильный стиль строки состояния, - это расширение Facebook Messenger, упомянутое в вопросе. Однако, похоже, это ошибка в самом расширении, поскольку все приложения, которые я пробовал, использующие стиль строки .LightContent
(например, Twitter), имеют такую же проблему - представленное расширение FB Messenger из приложения имеет строку состояния с текстом белого цвета.
Ответ 2
Решение, которое я использую довольно часто, - это создать класс контроллера базового представления, из которого все контроллеры представлений в моем приложении. Это имеет то преимущество, что позволяет использовать функциональные возможности стиля строки состояния на основе View-Control со стандартным (светлым или темным) стилем, который затем может быть переопределен на основе каждого контроллера при необходимости.
Контроллер базового представления также очень удобен, когда вы начинаете получать изменения на основе набора признаков, настраиваемые анимации перехода, которые вы хотите использовать для большинства контроллеров просмотра, центральную точку для отслеживания аналитики и другие полезные вещи.
Да, вам нужно пройти через потенциально большую исходную базу и изменить все свои UIViewController
на BaseViewController
s, но это часто так же просто, как глобальный поиск и замена.
Вот что выглядит BaseViewController
со способами, связанными со статусом:
class BaseViewController: UIViewController {
var statusBarHidden: Bool = false { didSet { setNeedsStatusBarAppearanceUpdate() } }
var statusBarStyle: UIStatusBarStyle = .lightContent { didSet { setNeedsStatusBarAppearanceUpdate() } }
var statusBarUpdateAnimation: UIStatusBarAnimation = .fade { didSet { setNeedsStatusBarAppearanceUpdate() } }
override var preferredStatusBarStyle: UIStatusBarStyle { return statusBarStyle }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { return statusBarUpdateAnimation }
override var prefersStatusBarHidden: Bool { return statusBarHidden }
}
Для всех контроллеров, использующих стиль по умолчанию, вам не нужно ничего особенного:
class ViewController: BaseViewController { }
В тех случаях, когда вам нужна черная строка состояния, выполните:
class DarkStatusBarViewController: BaseViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
statusBarStyle = .default
}
}
Обратите внимание, что вы можете переименовать DarkStatusBarViewController
выше в DarkStatusBarBaseViewController
и извлечь из него вместо BaseViewController
, когда вам нужна темная строка состояния. Затем вам не нужно дублировать код состояния в каждом контроллере представления, который ему нужен, и вы поддерживаете приятную линейную связь для всех ваших BaseViewController
функциональных возможностей.