barTintColor не применяется, если NavigationBar имеет большие заголовки

Я обновляю приложение, которое было скомпилировано на Xcode 10 и нормально работает до iOS 13. Я хотел внести некоторые изменения, перекомпилированные на Xcode 11, и теперь у меня проблема с barTintColor.

Если для параметра "Большие заголовки" установлено значение "Всегда", пользовательский цвет barTintColor не применяется - я просто получаю серый цвет по умолчанию. Если для параметра "Большие заголовки" установлено значение "Никогда", пользовательский цвет barTintColor применяется должным образом. Если для параметра "Большие заголовки" установлено значение "Автоматически", панель NavBar по умолчанию становится серой, когда отображаются большие заголовки, и мой собственный цвет, когда отображаются небольшие заголовки. Например, когда TableView под моей панелью навигации выдвигается вверх, большой заголовок по умолчанию переключается на маленький заголовок, а моя панель NavBar меняет цвет. Нормальным поведением было бы, чтобы это всегда был мой собственный цвет.

Соответствующий код из моего класса ViewController с последней строкой, которая устанавливает barTintColor:

override func viewDidLoad() {
    super.viewDidLoad()

    setDelegates()
    setTableViewHeightForCollapsingHeaders()
    setNavigtionBarItems()
    doSplitViewManagement()
}


override func viewWillAppear(_ animated: Bool) {
    clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed
    super.viewWillAppear(animated)
    updateUI()
}

fileprivate func setNavigtionBarItems() {
    //set up UI buttons
    navigationItem.leftBarButtonItem = editButtonItem
    let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
    navigationItem.rightBarButtonItem = addButton

    navigationController?.navigationBar.barTintColor = UIColor(hex: 0x5da0a2)

}

Есть идеи, почему поведение изменилось и как это исправить?

3 ответа

Решение

Начиная с iOS 13 появился новый API https://developer.apple.com/documentation/uikit/uinavigationbarappearance.

Свойство backgroundColor, которое вы ищете, находится в суперклассе https://developer.apple.com/documentation/uikit/uibarappearance.

Дополнительный пример кода здесь https://developer.apple.com/documentation/uikit/uinavigationcontroller/customizing_your_app_s_navigation_bar

Документация Apple, на которую указывает Глотча, была критически важна для решения проблемы, хотя это было немного больше. Вот обновленная версия моего setNavigationBarItems(), которая работает в iOS 13:

    fileprivate func setNavigtionBarItems() {

    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithDefaultBackground()
        appearance.backgroundColor = myBackgroundColor

        navigationController?.navigationBar.standardAppearance = appearance
        navigationController?.navigationBar.scrollEdgeAppearance = appearance
        //navigationController?.navigationBar.compactAppearance = appearance

    } else {
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = myBackgroundColor
    }

Ключевым моментом в моем случае было то, что моя панель навигации была установлена ​​(в автоматическом раскладке) с "Большие заголовки" как "Автоматически". Это делает необходимым включить строку.scrollEdgeAppearance, чтобы настраиваемый внешний вид применялся при переходе от большого к компактному. Оказалось, что строка.compactAppearance не нужна, потому что я использую один и тот же цвет для обоих. Если мне нужны разные настройки внешнего вида для большого и компактного, то также будет полезна строка с.compactAppearance.

Если вы хотите, чтобы одно место делало это для всего приложения:

      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        let barBackgroundColor = UIColor(displayP3Red: 47/255, green: 54/255, blue: 64/255, alpha: 1.0)
        
        let appearance = UINavigationBarAppearance()
        appearance.configureWithDefaultBackground()
        appearance.backgroundColor = barBackgroundColor
        appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
        appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

        UINavigationBar.appearance().standardAppearance = appearance
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
    
        return true
    }
Другие вопросы по тегам