/// Navigation bar colors for `ColorableNavigationController`, called on `push` & `pop` actions
public protocol NavigationBarColorable: UIViewController {
var navigationTintColor: UIColor? { get }
var navigationBarTintColor: UIColor? { get }
}
public extension NavigationBarColorable {
var navigationTintColor: UIColor? { return nil }
}
定义自定义NavigationController子类:
class AppNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
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)
}
super.pushViewController(viewController, animated: animated)
}
override open func popViewController(animated: Bool) -> UIViewController? {
if let colors = previousViewController as? NavigationBarColorable {
setNavigationBarColors(colors)
}
// 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 }
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
]
navigationBar.tintColor = tintColor
}
navigationBar.barTintColor = colors.navigationBarTintColor
}
}
extension FirstViewController: NavigationBarColorable {
public var navigationBarTintColor: UIColor? { UIColor.red }
public var navigationTintColor: UIColor? { UIColor.white }
}
extension SecondViewController: NavigationBarColorable {
public var navigationBarTintColor: UIColor? { UIColor.blue }
public var navigationTintColor: UIColor? { UIColor.orange }
}
2条答案
按热度按时间fnx2tebb1#
要在iOS10中设置navigationBar的颜色变化动画,您需要在动画块内设置颜色后调用
layoutIfNeeded
。示例代码:
我还想通知苹果doesn’t officialy support动画在这样的属性,如barTintColor,所以该方法可以在任何时候打破.
如果您在动画块期间调用导航栏上的-layoutIfNeeded,它应该更新其背景属性,但鉴于这些属性的性质,实际上还没有任何类型的保证,您可以动画其中任何一个。
j2qf4p5b2#
交互式动画
定义协议:
定义自定义
NavigationController
子类:现在,您可以在
AppNavigationController
内的任何控制器中符合NavigationBarColorable
,并为它提供任何您想要的颜色。不要忘记实现这个有用的扩展: