如何为导航栏设置 CAGradientLayer 动画
Posted
技术标签:
【中文标题】如何为导航栏设置 CAGradientLayer 动画【英文标题】:How to animate CAGradientLayer for a navigation bar 【发布时间】:2019-06-26 03:56:41 【问题描述】:我们的导航栏使用 CAGradientLayer 来产生渐变效果。现在我们希望渐变颜色动态变化
我们使用下面的代码来实现渐变效果
let gradientLayer = CAGradientLayer()
var updatedFrame = self.navigationController!.navigationBar.bounds
updatedFrame.size.height += UIApplication.shared.statusBarFrame.size.height
gradientLayer.frame = updatedFrame
gradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor] // start color and end color
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) // Horizontal gradient start
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0) // Horizontal gradient end
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.navigationController!.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
我们试图在这个图层上添加动画,但它不起作用
let animation = CABasicAnimation(keyPath: "locations")
animation.fromValue = [0,0.5]
animation.toValue = [0,0.9]
animation.autoreverses = true
animation.repeatCount = Float.infinity
gradientLayer.add(animation,forKey: nil)
我注意到这种设置渐变颜色的方式实际上是设置背景图片。我认为这就是为什么动画不起作用的原因,因为设置图像是一个原子动作。
我搜索了其他设置渐变效果的方法,但没有运气。那么是否可以在导航栏上实现渐变效果动画呢?
【问题讨论】:
我不认为这是可能的。正如你所说,正如我所知,它只是放置一个图像来产生渐变效果。 【参考方案1】:我仍然没有找到为导航栏的 CAGradientLayer 设置动画的方法。但是,如果您只想在导航栏上简单地添加动画而不关心它是否真的是导航栏的一部分,我找到了一种解决方法。
我没有更改导航栏的图层,而是在导航栏后面放置了一个图层具有渐变动画的 UIView。
// create a view
// set its size the same as the navigation bar
let gradientView = UIView(frame: CGRect(x:0,y:0,width:self.navigationController!.navigationBar.frame.size.width,height:(self.navigationController!.navigationBar.frame.size.height+UIApplication.shared.statusBarFrame.height)))
view.addSubview(gradientView)
// add animation on this view
let anAnimation = CABasicAnimation(keyPath: "backgroundColor")
anAnimation.duration = 1.5;
anAnimation.repeatCount = 1;
anAnimation.autoreverses = false;
animation.fromValue = [0,0.5]
animation.toValue = [0,0.9]
gradientView.layer.add(anAnimation,forKey: "backgroundColor")
// hide the navigation bar's background image
self.navigationController!.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
就像在导航栏上添加动画一样(实际上不是)。
【讨论】:
以上是关于如何为导航栏设置 CAGradientLayer 动画的主要内容,如果未能解决你的问题,请参考以下文章
如何为 UISplitviewController 导航栏图像使用单个图像?
你如何为 UIImagePickerController 的导航栏着色/自定义?