Как изменить цвет текста строки состояния (Status Bar) в iOS (Swift)
Правильное решение для iOS 13+ с UINavigationController
Проблема, с которой вы столкнулись, действительно распространена. Основная причина — UINavigationController "перехватывает" управление строкой состояния у своих дочерних контроллеров. Вот пошаговое решение для iOS 13+.
Шаг 1: Настройка Info.plist
Убедитесь, что в Info.plist установлено:
UIViewControllerBasedStatusBarAppearance → YES
Это позволяет каждому ViewController индивидуально управлять строкой состояния.
Шаг 2: Создайте кастомный UINavigationController
Создайте подкласс UINavigationController и переопределите в нём childForStatusBarStyle:
class CustomNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
return topViewController
}
}
Это заставит NavigationController делегировать управление строкой состояния текущему верхнему ViewController.
Шаг 3: Переопределите preferredStatusBarStyle в ваших ViewController
В каждом ViewController, где нужен свой стиль:
class ViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent // или .darkContent
}
override func viewDidLoad() {
super.viewDidLoad()
setNeedsStatusBarAppearanceUpdate()
}
}
Шаг 4: Используйте кастомный NavigationController в Storyboard
В Storyboard выберите ваш NavigationController и в Identity Inspector измените Class на CustomNavigationController.
Альтернативный вариант без подкласса
Если не хотите создавать подкласс, можно переопределить preferredStatusBarStyle напрямую в NavigationController:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.barStyle = .black
}
}
Установка barStyle = .black автоматически делает текст Status Bar белым.
Важные моменты:
- iOS 13+: UIApplication.shared.statusBarStyle устарел и не работает
- UINavigationController: всегда переопределяет childForStatusBarStyle, если не указано иное
- Анимация: для плавного изменения используйте
UIView.animateсsetNeedsStatusBarAppearanceUpdate
Полный рабочий пример:
// CustomNavigationController.swift
import UIKit
class CustomNavigationController: UINavigationController {
override var childForStatusBarStyle: UIViewController? {
return topViewController
}
}
// FirstViewController.swift
class FirstViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
// SecondViewController.swift
class SecondViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
}
Теперь каждый экран будет иметь свой стиль строки состояния, а UINavigationController не будет мешать.
<<Простое решение через UINavigationBar.appearance()
Если вам нужно единое оформление для всего приложения или вы не хотите создавать подклассы, используйте глобальную настройку через appearance:
// AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Устанавливаем тёмный стиль Navigation Bar
UINavigationBar.appearance().barStyle = .black
// Это автоматически сделает текст Status Bar белым
return true
}
Этот метод работает во всех версиях iOS, начиная с iOS 7. Он простой и не требует изменений в каждом ViewController. Минус — одинаковый стиль для всех экранов.
Если нужно переключить обратно на тёмный текст (например, на светлом фоне), просто установите:
UINavigationBar.appearance().barStyle = .default
Для более тонкой настройки можно комбинировать с установкой цвета Navigation Bar:
UINavigationBar.appearance().barTintColor = UIColor.black
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor.white]