How do I transition/animate color of UINavigationBar?

前端 未结 2 509
再見小時候
再見小時候 2021-02-01 02:52

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 <

2条回答
  •  一向
    一向 (楼主)
    2021-02-01 03:48

    You can overwrite the push and pop methods of UINavigationController to set the bar color. I've stored the bar color corresponding to a view controller in its navigation item with a custom subclass of UINavigationItem. The following code works for me in iOS 11 for full and for interactive transitions as well:

    import UIKit
    
    class NavigationItem: UINavigationItem {
        @IBInspectable public var barTintColor: UIColor?
    }
    
    class NavigationController: UINavigationController, UIGestureRecognizerDelegate {
        func applyTint(_ navigationItem: UINavigationItem?) {
            if let item = navigationItem as? NavigationItem {
                self.navigationBar.barTintColor = item.barTintColor
            }
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            applyTint(self.topViewController?.navigationItem)
            self.interactivePopGestureRecognizer?.delegate = self
        }
        override func pushViewController(_ viewController: UIViewController, animated: Bool) {
            applyTint(viewController.navigationItem)
            super.pushViewController(viewController, animated: animated)
        }
    
        override func popViewController(animated: Bool) -> UIViewController? {
            let viewController = super.popViewController(animated: animated)
    
            applyTint(self.topViewController?.navigationItem)
            return viewController
        }
    
        override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? {
            let result = super.popToViewController(viewController, animated: animated)
    
            applyTint(viewController.navigationItem)
            return result
        }
    
        override func popToRootViewController(animated: Bool) -> [UIViewController]? {
            let result = super.popToRootViewController(animated: animated)
    
            applyTint(self.topViewController?.navigationItem)
            return result
        }
    
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    
        func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer)
        }
    }
    

    Note: The coordination of the color animation is done by the navigation controller

提交回复
热议问题