Последнее обновление (Xcode 10+ / Swift 4.2+)
Эта статья оставлена без изменений для тех, кто хочет понять логику различных подходов, которые присутствовали в течение последних нескольких лет. Между тем, начиная с Xcode 10, первый подход Swift 4.2 устарел и больше не поддерживается (т.е. не вступит в силу, если вы попытаетесь использовать его). Он по-прежнему используется для вашей информации, чтобы лучше понять обоснование Plist.info
флага и практику настройки.
Важное уточнение
Очень важно понимать два подхода к настройке внешнего вида строки состояния. Они разные и не должны смешиваться.
Первый подход - один цвет для всего приложения (УСТАРЕЛО начиная с iOS7)
В info.plist вы найдете или создадите ключ с именем
View controller-based status bar appearance
и установите его в NO .
Что оно делает? По сути, он устанавливает параметр, который говорит, что в вашем приложении внешний вид строки состояния не определяется индивидуально каждым контроллером представления . Это очень важно понять. Это означает, что у вас есть единые настройки для всего приложения, для всех экранов. Существует две настройки: default
черный текст на белом фоне или lightContent
белый текст на черном фоне.
Чтобы настроить один из них ( один параметр для всех экранов ):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent // .default
return true
}
Таким образом, вам не нужно восстанавливать этот параметр на каждом контроллере представления. Тем не менее, вы всегда можете прибегнуть к этому методу, чтобы добровольно изменить внешний вид.
Второй подход - индивидуальный цвет для каждого контроллера вида
Это наоборот. Чтобы заставить его работать, перейдите к info.plist и установите
View controller-based status bar appearance
в ДА
Таким образом, всякий раз, когда новый контроллер представления открыт, стиль строки состояния устанавливается индивидуально, если вы вставляете эту реализацию в каждый UIViewController
необходимый вам экземпляр:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent // .default
}
У вас так же, как в первом, установить темный или светлый стиль для строки состояния, индивидуально для каждого контроллера представления.
Это свойство выбирается UIKit в двух сценариях:
- При инициализации экрана, когда готовится пользовательский интерфейс.
- После звонка
setNeedsStatusBarAppearanceUpdate()
в коде.
В последнем случае вы имеете право манипулировать внешним видом строки состояния с помощью следующего кода:
var isDark = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return isDark ? .lightContent : .default
}
func toggleAppearance() {
isDark.toggle()
}
Затем, всякий раз, когда вы звоните toggleAppearance()
, изменение стиля строки состояния будет вызвано.
Третий подход - взломать!
Есть взлом, который позволяет получить доступ к строке состояния напрямую:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = UIColor.blue
}
return true
}
Зачем взламывать? Если вам нужен цвет строки состояния, отличный от черного или белого, вы используете недокументированный API. Вы получаете statusBar
объект с помощью KVC и устанавливаете его цвет фона. Объект, который вы получаете таким образом UIStatusBar
, является производным UIView
и, таким образом, естественно поддерживает backgroundColor
свойство. Это грязный, недопустимый способ, но пока это единственный способ настроить пользовательский цвет для строки состояния (без учета UINavigationBar
подхода, который позволяет полностью настроить внешний вид панели навигации и строки состояния). Это может привести к отклонению вашего приложения. Но, возможно, тебе повезло. И если это так, в некоторых сложных обстоятельствах (например, иерархия вложенных, дочерних контроллеров и контроллеров представления) это может быть в значительной степени единственным или, по крайней мере, менее сложным способом настройки внешнего вида строки состояния (например, чтобы сделать ее прозрачной)
Xcode 10+, Swift 4.2
Альтернатив больше нет: разработчик должен позволить каждому контроллеру представления определять внешний вид строки состояния, устанавливая флаг в YES (или опуская это действие, потому что это YES по умолчанию) и следуя приведенным выше инструкциям.
бонус
Решение на основе хака, которое вы можете (хотя и не рекомендуется) использовать в сложных обстоятельствах, чтобы добровольно изменить внешний вид строки состояния на любом этапе. Что касается цвета, следующий метод расширения делает именно то, что вы могли бы сделать с обычным подходом. Вы можете настроить его под свои нужды.
extension UIViewController {
func setStatusBarStyle(_ style: UIStatusBarStyle) {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
}
}
}