Кроме того, почему он не работает, он не интерактивный. Так что это не будет работать правильно, если пользователь проведет пальцем назад и не синхронизируется с анимацией навигации. Итак, если вы хотите работающее интерактивное решение, то мы идем:
Определение протокола для пользовательского цвета:
/// Navigation bar colors for `ColorableNavigationController`, called on `push` & `pop` actions
public protocol NavigationBarColorable: class {
var navigationTintColor: UIColor? { get }
var navigationBarTintColor: UIColor? { get }
}
public extension NavigationBarColorable {
var navigationTintColor: UIColor? { return nil }
}
Подкласс UINavigationController
и переопределить методы навигации:
/**
UINavigationController with different colors support of UINavigationBar.
To use it please adopt needed child view controllers to protocol `NavigationBarColorable`.
- note: Don't forget to set initial tint and barTint colors
*/
class AppNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
navigationBar.setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
navigationBar.shadowImage = UIImage()
if let colors = rootViewController as? NavigationBarColorable {
setNavigationBarColors(colors)
}
}
private var previousViewController: UIViewController? {
guard viewControllers.count > 1 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
override open func pushViewController(_ viewController: UIViewController, animated: Bool) {
if let colors = viewController as? NavigationBarColorable {
setNavigationBarColors(colors)
}
setTabBarHidden(viewController is TabBarHidable)
super.pushViewController(viewController, animated: animated)
}
override open func popViewController(animated: Bool) -> UIViewController? {
if let colors = previousViewController as? NavigationBarColorable {
setNavigationBarColors(colors)
}
setTabBarHidden(previousViewController is TabBarHidable)
// Let's start pop action or we can't get transitionCoordinator()
let popViewController = super.popViewController(animated: animated)
// Secure situation if user cancelled transition
transitionCoordinator?.animate(alongsideTransition: nil, completion: { [weak self] context in
guard let `self` = self else { return }
self.setTabBarHidden(self.topViewController is TabBarHidable)
guard let colors = self.topViewController as? NavigationBarColorable else { return }
self.setNavigationBarColors(colors)
})
return popViewController
}
override func popToRootViewController(animated: Bool) -> [UIViewController]? {
if let colors = rootViewController as? NavigationBarColorable {
setNavigationBarColors(colors)
}
let controllers = super.popToRootViewController(animated: animated)
return controllers
}
private func setNavigationBarColors(_ colors: NavigationBarColorable) {
if let tintColor = colors.navigationTintColor {
navigationBar.titleTextAttributes = [
.foregroundColor : tintColor,
.font : R.font.iranSansFaNumBold(size: 14)!
]
navigationBar.tintColor = tintColor
}
navigationBar.barTintColor = colors.navigationBarTintColor
}
}
А также согласовывайте и внедряйте методы протокола в каждом контроллере представления, для которого требуется пользовательский цвет навигации:
extension MyCustomViewController: NavigationBarColorable {
public var navigationBarTintColor: UIColor? { return .red }
public var navigationTintColor: UIColor? { return .blue }
}
Примечание1 : я добавил поддержку изменения цвета текста.
Примечание2 : Я использовал один из моих проектов в качестве основы для ответа, извините, если вы не видите ни одного общего наименования и т. Д.
Примечание3 : Как я уже упоминал в коде, не забудьте установить начальные цвета tint и barTint.