title: How do I transition/animate color of UINavigationBar?
body: <p>I have been searching for how to transition/animate the <code>barTintColor</code> of a <code>UINavigationBar</code> for a while now, and I only see different answers. Some use <code>UIView.animateWithDuration</code>, some use <code>CATransition</code>, but the most interesting ones, like <a href="https://stackoverflow.com/a/40250912/1203228">this one</a> use <code>animate(alongsideTransition animation..</code>, which I like the sound of, but I can't get it working properly. Am I doing something wrong?</p>
  
  <p>Many specify that I can simply use the <code>transitionCoordinator</code> in <code>viewWillAppear:</code>. I have set up a fresh super tiny project like this:</p>
  
  <pre><code>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
      }
  }
  </code></pre>
  
  <p>With this code, this happens:
  <a href="https://i.stack.imgur.com/na5Ig.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/na5Ig.gif" alt="First"></a></p>
  
  <ul>
  <li>The push-transition from <code>First</code> to <code>Second</code> looks 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.</li>
  <li>The pop-transition from <code>Second</code> to <code>First</code> is completely wrong. It keeps the colors from <code>Second</code> until the transition is completely done.</li>
  <li>The drag-transition from <code>Second</code> to <code>First</code> looks 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.</li>
  <li>The drag-transition from <code>Second</code> to <code>First</code> but cancelled mid-drag and returning to <code>Second</code> is completely screwed up. It looks fine until <code>Second</code> is completely back in control, and then it suddenly changes itself to <code>First</code>-colors. This should not happen.</li>
  </ul>
  
  <p>I made a few changes to my <code>RootViewController</code> to make it a little better. I removed <code>viewWillAppear:</code> completely, and changed it with this:</p>
  
  <pre><code>class RootViewController:UIViewController{
  
      override func willMove(toParentViewController parent: UIViewController?) {
          if let last = self.navigationController?.viewControllers.last as? RootViewController{
              if last == self &amp;&amp; self.navigationController!.viewControllers.count &gt; 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
      }
  }
  </code></pre>
  
  <p>With this updated code, I get this:
  <a href="https://i.stack.imgur.com/pnkGe.gif" rel="noreferrer"><img src="https://i.stack.imgur.com/pnkGe.gif" alt="Second"></a></p>
  
  <p>A few observations:</p>
  
  <ul>
  <li>The transition from <code>First</code> to <code>Second</code> is the same</li>
  <li>The pop-transition from <code>Second</code> to <code>First</code> is 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.</li>
  <li>The drag-transition from <code>Second</code> to <code>First</code> also 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.</li>
  </ul>
  
  <p>What am I doing wrong? How am I supposed to do this?</p>
  
  <p>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?</p>