Как изменить цвет панели навигации (UINavigationBar) в Swift?
Правильный способ изменения цвета UINavigationBar в Swift (iOS 13+)
Ваша проблема типична для начинающих разработчиков. Начиная с iOS 13, Apple изменила подход к кастомизации UINavigationBar. Старые свойства, такие как barTintColor и backgroundColor, больше не работают так, как раньше. Теперь используется UINavigationBarAppearance.
Решение для iOS 13 и новее
Лучший способ — настроить внешний вид через UINavigationBarAppearance и применить его глобально или к конкретному навигационному контроллеру. Вот полный пример:
// В AppDelegate.swift или в любом месте перед отображением навигации
func setupNavigationBarAppearance() {
// Создаем объект appearance
let appearance = UINavigationBarAppearance()
// Настраиваем цвета
appearance.configureWithOpaqueBackground() // Убирает прозрачность
appearance.backgroundColor = UIColor.systemBlue // Цвет фона
// Настраиваем цвет заголовка
appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
// Настраиваем цвет кнопок (back button, bar button items)
let buttonAppearance = UIBarButtonItemAppearance()
buttonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.white]
appearance.buttonAppearance = buttonAppearance
// Настраиваем цвет стрелки "Назад"
appearance.backButtonAppearance = buttonAppearance
// Применяем глобально ко всем UINavigationBar
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().compactAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
Вызовите этот метод в application(_:didFinishLaunchingWithOptions:):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
setupNavigationBarAppearance()
return true
}
Если нужно изменить цвет только для одного экрана
Просто примените appearance к конкретному navigationController:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = UIColor.systemGreen
appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
navigationController?.navigationBar.standardAppearance = appearance
navigationController?.navigationBar.compactAppearance = appearance
navigationController?.navigationBar.scrollEdgeAppearance = appearance
}
Почему ваш старый код не работал?
- barTintColor — устарел с iOS 13. Он игнорируется, если установлен
scrollEdgeAppearance. - backgroundColor — работает только для фона, но не влияет на прозрачность.
- isTranslucent — если установить
false, панель станет непрозрачной, но цвет все равно нужно задавать через appearance.
Полный пример с восстановлением стандартного цвета
Если вы хотите вернуть стандартный цвет на других экранах, сохраните исходный appearance:
// Сохраняем дефолтный appearance
let defaultAppearance = UINavigationBar.appearance().standardAppearance
// На экране с кастомным цветом
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let customAppearance = UINavigationBarAppearance()
customAppearance.configureWithOpaqueBackground()
customAppearance.backgroundColor = UIColor.orange
navigationController?.navigationBar.standardAppearance = customAppearance
}
// При уходе с экрана
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.navigationBar.standardAppearance = defaultAppearance
}
Теперь ваша панель навигации будет синей с белым текстом на всех экранах. Не забудьте импортировать UIKit — это все, что нужно.
<<Альтернативный подход: через Storyboard и User Defined Runtime Attributes
Если вы не хотите писать много кода, можно настроить цвет UINavigationBar прямо в Storyboard с помощью User Defined Runtime Attributes. Это особенно удобно для быстрого прототипирования.
Как сделать:
- Выберите ваш Navigation Controller в Storyboard.
- Перейдите на вкладку "Identity Inspector" (четвертая иконка справа).
- В разделе "User Defined Runtime Attributes" добавьте новые ключи:
Key Path: navigationBar.standardAppearance.backgroundColor
Type: Color
Value: выберите нужный цвет (например, System Blue)
Key Path: navigationBar.standardAppearance.titleTextAttributes
Type: Dictionary
Value: добавьте ключ NSForegroundColorAttributeName со значением White Color
Также добавьте для compactAppearance и scrollEdgeAppearance, если нужно.
Минусы этого подхода:
- Сложно поддерживать при изменении дизайна.
- Нельзя легко переиспользовать между разными проектами.
- Нет проверки типов — легко ошибиться в названии ключа.
Поэтому для продакшена рекомендую использовать первый способ с кодом. А этот метод подойдет для быстрых экспериментов или если вы только учитесь.