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逐一设置透明度