没有插值的 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.
如何在不指定 fromValue
、byValue
或 toValue
的情况下完成这项工作?
在这里,我只是对 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 中设置 toValue
和 fromValue
,因为运行时获取 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)
...对此(注意 fromValue
和 toValue
被省略):
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)
但是,我不推荐这种方法。始终同时提供 fromValue
和 toValue
更为可靠。是的,它多了两行代码,但这是为避免混淆而付出的很小的代价。有时,清晰就是简单。
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.
如何在不指定 fromValue
、byValue
或 toValue
的情况下完成这项工作?
在这里,我只是对 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 中设置 toValue
和 fromValue
,因为运行时获取 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)
...对此(注意 fromValue
和 toValue
被省略):
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)
但是,我不推荐这种方法。始终同时提供 fromValue
和 toValue
更为可靠。是的,它多了两行代码,但这是为避免混淆而付出的很小的代价。有时,清晰就是简单。