如何为导航栏设置 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 导航栏图像使用单个图像?

如何为 UITableView 部分标题动态设置背景颜色?

你如何为 UIImagePickerController 的导航栏着色/自定义?

如何为导航到实现底部导航栏的活动中的上一个片段进行后推操作?

如何为 A Person View Controller 的导航栏添加返回按钮?