CAGradientLayer 颜色更改动画未执行

Posted

技术标签:

【中文标题】CAGradientLayer 颜色更改动画未执行【英文标题】:CAGradientLayer color change animation not executing 【发布时间】:2016-07-25 07:43:35 【问题描述】:

我正在尝试制作一个非常基本的CAGradientLayer 动画。我有一个基本的 2 色 CAGradientLayer 设置并添加到我的 UIViewController

// Set up the gradient layer.
var gradientLayer: CAGradientLayer! 
    let layer = CAGradientLayer()
    layer.frame = self.view.bounds
    layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
    layer.locations = [0.0, 1.0]
    return layer

我正在尝试使用以下代码对其进行动画处理:

@IBAction func changeBackground(sender: AnyObject) 
    let oldColors = self.gradientLayer.colors
    let newColors = [UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor]
    self.gradientLayer.colors = newColors
    let animation: CABasicAnimation = CABasicAnimation(keyPath: "colors")

    animation.fromValue = oldColors
    animation.toValue = newColors
    animation.duration = 0.3
    animation.removedOnCompletion = true
    animation.fillMode = kCAFillModeForwards
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.delegate = self

    self.gradientLayer.addAnimation(animation, forKey: "animateGradientColorChange")

但是,此代码不会对CAGradientLayer 产生任何更改。我在这里做错了什么?

【问题讨论】:

【参考方案1】:

您每次都从您的gradientLayer 属性返回一个新的layer 对象。您需要对其进行一些更改,以便延迟启动:

lazy var gradientLayer: CAGradientLayer! = 
    let layer = CAGradientLayer()
    layer.frame = self.view.bounds
    layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
    layer.locations = [0.0, 1.0]
    return layer
()

为了完整起见,您最初拥有的是一个计算属性,这意味着每次访问它时都会执行代码。使用惰性属性,代码只执行一次,当第一次访问属性时,然后返回相同的对象。

可以通过这个游乐场观察到差异:

//: Playground - noun: a place where people can play

import UIKit

struct Dummy 

    var gradientLayer: CAGradientLayer! 
        let layer = CAGradientLayer()
        layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
        layer.locations = [0.0, 1.0]
        return layer
    

    lazy var lazyGradientLayer: CAGradientLayer! = 
        let layer = CAGradientLayer()
        layer.colors = [UIColor.redColor().CGColor, UIColor.yellowColor().CGColor]
        layer.locations = [0.0, 1.0]
        return layer
    ()


var dummy = Dummy()

let l1 = dummy.gradientLayer
let l2 = dummy.gradientLayer

let lazy1 = dummy.lazyGradientLayer
let lazy2 = dummy.lazyGradientLayer

【讨论】:

以上是关于CAGradientLayer 颜色更改动画未执行的主要内容,如果未能解决你的问题,请参考以下文章

在两个 CAGradientLayer 颜色设置之间连续渐变?

为啥我的 CAGradientLayer 为所有更改设置动画?

使用滑块实时更改 CAGradientLayer 的颜色

如何像屏幕保护程序一样更改 CAGradientLayer 的颜色?

我可以通过 IBAction 更改 CAGradientLayer() 颜色吗?

如何为导航栏设置 CAGradientLayer 动画