iOS-导航栏透明度和barTintColor渐变过渡

iOS-导航栏透明度和barTintColor渐变过渡

Demo:github

1.对UIViewController进行扩展,添加关联属性navBarBarTintColor和navBarBgAlpha
extension UIViewController {
    
    struct AssociatedKeys {
        static var navBarBgAlpha: CGFloat = 1.0
        static var navBarBarTintColor: UIColor = UIColor.red
    }

    var navBarBgAlpha: CGFloat {
        get {
            let alpha = objc_getAssociatedObject(self, &AssociatedKeys.navBarBgAlpha) as? CGFloat
            if alpha == nil {
                return 1.0
            }else{
                return alpha!
            }
            
        }
        set {
            var alpha = newValue
            if alpha > 1 {
                alpha = 1
            }
            if alpha < 0 {
                alpha = 0
            }
            
            objc_setAssociatedObject(self, &AssociatedKeys.navBarBgAlpha, alpha, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            
            let barBackgroundView = self.navigationController?.navigationBar.subviews[0]
            if #available(iOS 11,*) {
                if let subViews = barBackgroundView?.subviews {
                    for v in subViews {
                        v.alpha = self.navBarBgAlpha
                    }
                }
            }else{
                barBackgroundView?.alpha = self.navBarBgAlpha
            }
        }
    }
    
    var navBarBarTintColor:UIColor{
        get {
            let color = objc_getAssociatedObject(self, &AssociatedKeys.navBarBarTintColor) as? UIColor
            if color == nil {
                return UIColor.red
            }else{
                return color!
            }
            
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.navBarBarTintColor, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            
            //设置导航栏背景色
            navigationController?.navigationBar.barTintColor = newValue
            
        }
        
    }
}
2.在需要进行渐变的controller或基类中实现代码
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.navBarBarTintColor = self.navBarBarTintColor
        self.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in
            self.navBarBgAlpha = self.navBarBgAlpha
            self.navBarBarTintColor = self.navBarBarTintColor
            }, completion: nil)
    }
iOS11的bug

self.navigationController?.navigationBar.subviews[0] 是 _UIbarBackGround 类型
由于在iOS11上直接设置_UIbarBackGround的透明度无效,于是增加iOS11的判断,并对_UIbarBackGround 的subView逐一设置透明度

最终效果如下
image

推荐阅读更多精彩内容