下面的问题是给予缩放动画的持续时间会覆盖旋转动画。
还有其他方法可以同时为不同持续时间的CALayer刻度和旋转设置动画吗?
// Animate arrowhead rotation
CATransaction.begin()
CATransaction.setAnimationDuration(0.2)
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut))
let arrowAngle = atan2(path.currentPoint.y - previousPoint.y,
path.currentPoint.x - previousPoint.x) + (.pi * 0.5)
let rotationZ = CATransform3DRotate(CATransform3DIdentity, arrowAngle, 0, 0, 1)
arrowhead.transform = rotationZ
CATransaction.commit()
// Animate arrowhead scale
CATransaction.begin()
CATransaction.setAnimationDuration(1.5)
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut))
arrowhead.transform = CATransform3DConcat(rotationZ, arrowheadTransformScale)
CATransaction.commit()
答案 0 :(得分:2)
这里有效:
override func viewDidLoad() {
let box = CALayer()
box.frame = CGRect(x: 150, y: 300, width: 100, height: 100)
box.backgroundColor = UIColor.white.cgColor
view.layer.addSublayer(box)
let boxTransform = box.transform
let currentAngle = atan2(boxTransform.m12, boxTransform.m11)
let currentScale = getScale(for: box.affineTransform())
let targetAngle: CGFloat = .pi / 3
let targetScale: CGFloat = 2
// Set layer model's animated properties to their target values. Then the subsequent animations don't require isRemovedOnCompletion and fillMode to be set which would leave the layer model out of sync.
var affineTransform = CGAffineTransform(rotationAngle: targetAngle)
affineTransform = affineTransform.scaledBy(x: targetScale, y: targetScale)
box.setAffineTransform(affineTransform)
let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
rotate.fromValue = currentAngle
rotate.toValue = targetAngle
rotate.duration = 2
rotate.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
let scaleUp = CABasicAnimation(keyPath: "transform.scale")
scaleUp.fromValue = currentScale
scaleUp.toValue = targetScale
scaleUp.duration = 4
scaleUp.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
let rotateAndScale = CAAnimationGroup()
rotateAndScale.animations = [rotate, scaleUp]
rotateAndScale.duration = 4
// Setting key to "transform" overwrites the implicit animation created when setting the target values before the animation.
box.add(rotateAndScale, forKey: "transform")
}
func getScale(for t: CGAffineTransform) -> CGFloat {
return sqrt(t.a * t.a + t.c * t.c)
}