I have been searching for how to transition/animate the barTintColor of a UINavigationBar for a while now, and I only see different answers. Some use UIView.animateWithDuration, some use CATransition, but the most interesting ones, like this one use animate(alongsideTransition animation.., which I like the sound of, but I can't get it working properly. Am I doing something wrong?
Many specify that I can simply use the transitionCoordinator in viewWillAppear:. I have set up a fresh super tiny project like this:
class RootViewController:UIViewController{ //Only subclassed
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
transitionCoordinator?.animate(alongsideTransition: { [weak self](context) in
self?.setNavigationColors()
}, completion: nil)
}
func setNavigationColors(){
//Override in subclasses
}
}
class FirstViewController: RootViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "First"
}
override func setNavigationColors(){
navigationController?.navigationBar.barTintColor = UIColor.white
navigationController?.navigationBar.tintColor = UIColor.black
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.black]
navigationController?.navigationBar.barStyle = UIBarStyle.default
}
}
class SecondViewController: RootViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Second"
}
override func setNavigationColors(){
navigationController?.navigationBar.barTintColor = UIColor.black
navigationController?.navigationBar.tintColor = UIColor.white
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
navigationController?.navigationBar.barStyle = UIBarStyle.black
}
}
- The push-transition from
FirsttoSecondlooks perfect. All elements transition perfectly, maybe except the StatusBar, which instantly changes to white. I'd rather know how to transition it, but I'll accept it for now. - The pop-transition from
SecondtoFirstis completely wrong. It keeps the colors fromSeconduntil the transition is completely done. - The drag-transition from
SecondtoFirstlooks alright, when dragging all the way over. Again, the StatusBar instantly becomes black as soon as I start dragging, but I don't know if that's possible to fix. - The drag-transition from
SecondtoFirstbut cancelled mid-drag and returning toSecondis completely screwed up. It looks fine untilSecondis completely back in control, and then it suddenly changes itself toFirst-colors. This should not happen.
I made a few changes to my RootViewController to make it a little better. I removed viewWillAppear: completely, and changed it with this:
class RootViewController:UIViewController{
override func willMove(toParentViewController parent: UIViewController?) {
if let last = self.navigationController?.viewControllers.last as? RootViewController{
if last == self && self.navigationController!.viewControllers.count > 1{
if let parent = self.navigationController!.viewControllers[self.navigationController!.viewControllers.count - 2] as? RootViewController{
parent.setNavigationColors()
}
}
}
}
override func viewWillDisappear(_ animated: Bool) {
if let parent = navigationController?.viewControllers.last as? RootViewController{
parent.animateNavigationColors()
}
}
override func viewDidAppear(_ animated: Bool) {
self.setNavigationColors()
}
func animateNavigationColors(){
transitionCoordinator?.animate(alongsideTransition: { [weak self](context) in
self?.setNavigationColors()
}, completion: nil)
}
func setNavigationColors(){
//Override in subclasses
}
}
With this updated code, I get this:

A few observations:
- The transition from
FirsttoSecondis the same - The pop-transition from
SecondtoFirstis now animating correctly, except from the back-arrow, the back-text (and the statusBar, but yeah..). These are instantly changed to black. In the first gif, you could see that the back-arrow and the back-text also transitioned. - The drag-transition from
SecondtoFirstalso has this problem, the back-arrow and back-text are suddenly instantly black when starting. The barTint is fixed so that it doesn't get the wrong color when cancelling the drag.
What am I doing wrong? How am I supposed to do this?
What I want is to transition all elements smoothly. The tint of the back-button, the back-text, the title, the barTint, and the statusBar. Is this not possible?

