iOS动画:CADisplayLink与CAShapeLayer

时间:2015-06-20 15:42:16

标签: ios swift animation timer core-animation

我正在编写一个计时器,类似于时钟应用程序的水平版本中可用的计时器,除了它启动已满并向下运行为空。

我实现了计时器,它可以在更长的时间内运行,但它无法为快速动画设置足够的动画效果(我的目标是以最快的速度完成400毫秒的总动画时间),因为我使用drawRect方法进行动画处理。为了说明,这是我的计时器代码:

class SSTimerView: UIView {
    var timer: NSTimer?
    var startAngle: CGFloat = (CGFloat) (M_PI * 1.5)
    var endAngle: CGFloat = (CGFloat) (M_PI * 1.5) + (CGFloat) (M_PI * 2)
    var percent: CGFloat? = 100 

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

    override func drawRect(rect: CGRect) {
        var bezierPath = UIBezierPath()
        //Create our arc with the correct angles
        bezierPath.addArcWithCenter(CGPointMake(rect.size.width/2, rect.size.height/2),
            radius: 130,
            startAngle: startAngle,
            endAngle: (endAngle - startAngle) * (percent! / 100.0) + startAngle,
            clockwise: true
        )
        //Set the display for the path and stroke it.
        bezierPath.lineWidth = 20
        Slide.sharedInstance.currentInstruction!.colorFamily.lighterColor.setStroke()
        bezierPath.stroke()
    }
}

我一直在阅读CADisplayLink,我认为这可能是一个可行的选择,但我也听说CADisplayLink并不适合所有情况。这是其中之一吗?如果CADisplayLink在这里不合适,我应该使用哪个CA类?

1 个答案:

答案 0 :(得分:1)

如您所知,手动动画CADisplayLink始终优于NSTimer。 (有关讨论原因,请参阅WWDC 2014视频Building Interruptible and Responsive Interactions,从视频开始大约14分钟。)因此,如果您坚持使用现有模式,请务必转到CADisplayLink

但是如果你想为这条路径的绘图设置动画,CABasicAnimation就容易了:

var shapeLayer: CAShapeLayer!

func addShapeLayer() {
    shapeLayer     = CAShapeLayer()
    let startAngle = CGFloat(M_PI * 1.5)
    let endAngle   = startAngle + CGFloat(M_PI * 2)

    let bezierPath = UIBezierPath()

    bezierPath.addArcWithCenter(CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2),
        radius: 130.0,
        startAngle: startAngle,
        endAngle: endAngle,
        clockwise: true
    )

    shapeLayer.path        = bezierPath.CGPath
    shapeLayer.strokeColor = UIColor.blueColor().CGColor
    shapeLayer.fillColor   = UIColor.clearColor().CGColor
    shapeLayer.lineWidth   = 20.0

    view.layer.addSublayer(shapeLayer)
}

func animateShapeLayer() {
    let animation       = CABasicAnimation(keyPath: "strokeEnd")
    animation.duration  = 0.4
    animation.fromValue = 0.0
    animation.toValue   = 1.0
    shapeLayer.addAnimation(animation, forKey: "strokeEndAnimation")
}

如果您需要更多自定义行为,CADisplayLink方法很棒,但如果您只想在一定时间内为路径绘制设置动画,CABasicAnimation最简单(并且很可能提供最佳表现)。