没有插值的 CABasicAnimation

CABasicAnimation without interpolation values

Apple 的文档 link 指出:

The fromValue, byValue and toValue properties define the values being interpolated between. All are optional, and no more than two should be non-nil. The object type should match the type of the property being animated.

The interpolation values are used as follows:

  • All properties are nil. Interpolates between the previous value of keyPath in the target layer’s presentation layer and the current value of keyPath in the target layer’s presentation layer.

如何在不指定 fromValuebyValuetoValue 的情况下完成这项工作?

在这里,我只是对 cornerRadius 属性 的变化进行动画处理。

我知道如何使用 toValue 制作这个动画。但是我只想知道有没有比这更简单的代码来实现:

import UIKit
import PlaygroundSupport

let rect = CGRect(x: 0,y: 0, width: 300, height: 400)
let view = UIView(frame: rect)
view.backgroundColor = UIColor.yellow
PlaygroundPage.current.liveView = view

let layer = CALayer()
layer.backgroundColor = UIColor.red.cgColor
layer.frame = CGRect(x: 75, y: 75, width: 150, height: 150)
view.layer.addSublayer(layer)

layer.cornerRadius = 15
let animation = CABasicAnimation(keyPath:#keyPath(CALayer.cornerRadius))
animation.toValue = layer.bounds.width / 2
animation.duration = 1
layer.add(animation, forKey: nil)

在某些情况下,您已经设置了没有动画的层的最终值,您可以跳过在 CABasicAnimation 中设置 toValuefromValue,因为运行时获取 fromValue来自表示层的当前值,toValue来自模型层的当前值。

例如,在我自己的代码中,事实证明我可以减少这种指定动画的完整形式...

        let startValue = arrow.transform
        let endValue = CATransform3DRotate(startValue, .pi/4.0, 0, 0, 1)
        CATransaction.setDisableActions(true)
        arrow.transform = endValue
        let anim = CABasicAnimation(keyPath:#keyPath(CALayer.transform))
        anim.duration = 0.8
        let clunk = CAMediaTimingFunction(controlPoints:0.9, 0.1, 0.7, 0.9)
        anim.timingFunction = clunk
        anim.fromValue = startValue
        anim.toValue = endValue
        arrow.add(anim, forKey:nil)

...对此(注意 fromValuetoValue 被省略):

        CATransaction.setDisableActions(true)
        arrow.transform = CATransform3DRotate(arrow.transform, .pi/4.0, 0, 0, 1)
        let anim = CABasicAnimation(keyPath:#keyPath(CALayer.transform))
        anim.duration = 0.8
        let clunk = CAMediaTimingFunction(controlPoints:0.9, 0.1, 0.7, 0.9)
        anim.timingFunction = clunk
        arrow.add(anim, forKey:nil)

但是,我不推荐这种方法。始终同时提供 fromValuetoValue 更为可靠。是的,它多了两行代码,但这是为避免混淆而付出的很小的代价。有时,清晰就是简单。