我希望在特定时间点为3个不同的图像制作动画,使其表现得如此。
1) 1st image moves from (Xx, Yx) to (Xz,Yz)
2) Wait 10 seconds
3) 2nd image appears in place at Xa,Yb
4) Wait half as long as in step 2
5) Fade out 2nd image
6) 3rd image appears at the same place as 2nd image
如果这些图像的每个动画都在他们自己的CALayers上,我可以将CAKeyframeAnimation与多个图层一起使用吗?如果没有,那么采用交错动画的另一种方式是什么?
我正在尝试将扑克牌从屏幕外移动到特定位置,然后在几秒钟后在屏幕上显示其他一些技巧。
答案 0 :(得分:3)
不,您无法使用关键帧动画为多个图层设置动画。给定的CAAnimation只能作用于单个图层。顺便说一下,这包括组图层。
如果你所做的只是在直线上移动图像,淡出和淡入,你为什么不使用UIView动画呢?看一下名字以animateWithDuration开头的方法:动画:那些可以让你同时创建多个动画,然后完成块可以触发其他动画。
如果由于某种原因需要使用图层动画,可以使用beginTime属性(CAAnimation对象具有这些属性,因为它们符合CAMediaTiming协议。)对于不属于动画组的CAAnimations,使用
animation.beginTime = CACurrentMediaTime() + delay;
延迟是一个双倍,以秒表示延迟。
如果延迟为0,则动画将开始。
第三个选项是将视图控制器设置为动画的委托,并使用animationDidStop:finished:方法链接动画。在我看来,这最终是最容易实施的方法。
答案 1 :(得分:2)
关于单个动画组不能为不同图层的属性设置动画的说法是不正确的。它可以。该技术是将动画组附加到上层,并在各个动画的关键路径中引用子层的属性。
这里是一个完整的示例,仅用于演示目的。启动后,该项目将显示两个“足迹”,这些足迹会交替出现在屏幕顶部。
class ViewController: UIViewController, CAAnimationDelegate {
let leftfoot = CALayer()
let rightfoot = CALayer()
override func viewDidLoad() {
super.viewDidLoad()
self.leftfoot.name = "left"
self.leftfoot.contents = UIImage(named:"leftfoot")!.cgImage
self.leftfoot.frame = CGRect(x: 100, y: 300, width: 50, height: 80)
self.view.layer.addSublayer(self.leftfoot)
self.rightfoot.name = "right"
self.rightfoot.contents = UIImage(named:"rightfoot")!.cgImage
self.rightfoot.frame = CGRect(x: 170, y: 300, width: 50, height: 80)
self.view.layer.addSublayer(self.rightfoot)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.start()
}
}
func start() {
let firstLeftStep = CABasicAnimation(keyPath: "sublayers.left.position.y")
firstLeftStep.byValue = -80
firstLeftStep.duration = 1
firstLeftStep.fillMode = .forwards
func rightStepAfter(_ t: Double) -> CABasicAnimation {
let rightStep = CABasicAnimation(keyPath: "sublayers.right.position.y")
rightStep.byValue = -160
rightStep.beginTime = t
rightStep.duration = 2
rightStep.fillMode = .forwards
return rightStep
}
func leftStepAfter(_ t: Double) -> CABasicAnimation {
let leftStep = CABasicAnimation(keyPath: "sublayers.left.position.y")
leftStep.byValue = -160
leftStep.beginTime = t
leftStep.duration = 2
leftStep.fillMode = .forwards
return leftStep
}
let group = CAAnimationGroup()
group.duration = 11
group.animations = [firstLeftStep]
for i in stride(from: 1, through: 9, by: 4) {
group.animations?.append(rightStepAfter(Double(i)))
group.animations?.append(leftStepAfter(Double(i+2)))
}
group.delegate = self
self.view.layer.add(group, forKey: nil)
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
print("done")
self.rightfoot.removeFromSuperlayer()
self.leftfoot.removeFromSuperlayer()
}
}
说了这么多,我应该补充一点,如果要对诸如位置的核心属性进行动画处理,则使其成为视图并使用UIView关键帧动画来协调不同视图上的动画可能会更简单。仍然,关键是说用CAAnimationGroup无法完成 是错误的。