如何顺利完成无限动画

How to smoothly finish infinity animation

我有无穷大CABasicAnimation,它实际上通过增加和减少比例来模拟脉动:

scaleAnimation.fromValue = 0.5
scaleAnimation.toValue = 1.0
scaleAnimation.duration = 0.8

scaleAnimation.autoreverses = true
scaleAnimation.repeatCount = .greatestFiniteMagnitude
scaleAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)

我想在toValue中顺利停止这个动画。换句话说,我想让当前的动画循环结束,但停止重复。有没有一种干净利落的方法来做到这一点?我有一些关于冻结当前动画、删除它并创建一个带有时间偏移的新动画的想法,但也许有更好的方法?

有一种标准的方法可以干净利落地做到这一点——尽管如果您不知道它实际上非常棘手:

  1. 您要做的第一件事是将图层的比例设置为其 presentationLayer 的比例。

  2. 然后在图层上调用removeAllAnimations

  3. 现在制作一个快速动画,将图层的比例设置为 1。

这是一个可能的实现(为了额外加分,我想我们可以调整快速动画的持续时间以匹配当前比例,但我在这里懒得这样做):

@IBAction func doStop(_ sender: Any) {
    let lay = v.layer
    lay.transform = lay.presentation()!.transform
    lay.removeAllAnimations()
    CATransaction.flush()
    lay.transform = CATransform3DIdentity
    let scaleAnimation = CABasicAnimation(keyPath: "transform")
    scaleAnimation.duration = 0.4
    scaleAnimation.timingFunction = CAMediaTimingFunction(name: .easeOut)
    lay.add(scaleAnimation, forKey: nil)
}

结果: