CALayer 子类重复动画

CALayer Subclass Repeating Animation

我正在尝试创建一个每 x 秒执行一次动画的 CALayer 子类。在下面的示例中,我试图将背景从一种随机颜色更改为另一种颜色,但是当 运行 这在操场上似乎没有任何反应

import UIKit
import XCPlayground
import QuartzCore

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 200, height: 200))
XCPShowView("view", view)

class CustomLayer: CALayer {

    var colors = [
        UIColor.blueColor().CGColor,
        UIColor.greenColor().CGColor,
        UIColor.yellowColor().CGColor
    ]

    override init!() {
        super.init()

        self.backgroundColor = randomColor()

        let animation = CABasicAnimation(keyPath: "backgroundColor")

        animation.fromValue = backgroundColor
        animation.toValue = randomColor()
        animation.duration = 3.0
        animation.repeatCount = Float.infinity

        addAnimation(animation, forKey: "backgroundColor")

    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    private func randomColor() -> CGColor {
        let index = Int(arc4random_uniform(UInt32(colors.count)))
        return colors[index]
    }
}

let layer = CustomLayer()
layer.frame = view.frame
view.layer.addSublayer(layer)

重复动画的参数只设置一次,所以你不能在每次重复时改变颜色。您应该实现委托方法,而不是重复动画, animationDidStop:finished:,然后使用新的随机颜色从那里再次调用动画。我没有在操场上试过这个,但它在应用程序中运行正常。请注意,除了您拥有的其他 init 方法之外,您还必须实施 init!(layer layer: AnyObject!)。

import UIKit

class CustomLayer: CALayer {

    var newColor: CGColorRef!

    var colors = [
        UIColor.blueColor().CGColor,
        UIColor.greenColor().CGColor,
        UIColor.yellowColor().CGColor
    ]

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override init!(layer: AnyObject!) {
        super.init(layer: layer)
    }

    override init!() {
        super.init()
        backgroundColor = randomColor()
        newColor = randomColor()
        self.animateLayerColors()
    }


    func animateLayerColors() {
        let animation = CABasicAnimation(keyPath: "backgroundColor")
        animation.fromValue = backgroundColor
        animation.toValue = newColor
        animation.duration = 3.0
        animation.delegate = self

        addAnimation(animation, forKey: "backgroundColor")
    }

    override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {
        backgroundColor = newColor
        newColor = randomColor()
        self.animateLayerColors()
    }


    private func randomColor() -> CGColor {
        let index = Int(arc4random_uniform(UInt32(colors.count)))
        return colors[index]
    }
}