目标:
我的代码:
let animation = CABasicAnimation(keyPath: "transform.scale")
animation.fromValue = 1.0
animation.toValue = 1.5
animation.duration = 1.0
animation.autoreverses = true
animation.repeatCount = .greatestFiniteMagnitude
image1.layer.add(animation, forKey: animation.keyPath)
let animation2 = CABasicAnimation(keyPath: "transform.scale")
animation2.fromValue = 1.0
animation2.toValue = 2.0
animation2.duration = 1.0
animation2.fillMode = .forwards
let animation2b = CABasicAnimation(keyPath: "opacity")
animation2b.fromValue = 1.0
animation2b.toValue = 0.0
animation2b.duration = 1.0
animation2b.fillMode = .forwards
let animationGroup = CAAnimationGroup()
animationGroup.animations = [animation2, animation2b]
animationGroup.duration = 2.0
animationGroup.beginTime = 1.0
animationGroup.repeatCount = .greatestFiniteMagnitude
image2.layer.add(animationGroup, forKey: "scaleAndFade")
目标是在第一个动画之后开始第二个动画1.0。并且由于动画组的持续时间为2.0,而其中的动画只有1.0的持续时间,动画将从1.0开始,以2.0结束,然后再不再重复到3.0
这两个动画有时会匹配,但不会在每个构建中匹配。是否有一种更加可靠的方式来启动第二个动画,以便在初始动画的第一个完成动画结束时开始?这样他们就可以从那一点开始同步。谢谢你的帮助!
我对我们想要实现的目标有点不清楚,但我的感觉是,我们有两种观点,重复动画需要协调。为了演示如何做到这一点的一个例子,我选择让两个动画都放大,然后缩小:
这里的动画gif在几次重复之后就结束了,但实际上重复只会持续下去。
这简单地实现如下:
func step1() {
UIView.animate(withDuration: 1, animations: {
self.v1.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
self.v2.transform = .identity
}) { _ in
DispatchQueue.main.async {
self.step2()
}
}
}
func step2() {
UIView.animate(withDuration: 1, animations: {
self.v1.transform = .identity
self.v2.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
}) { _ in
DispatchQueue.main.async {
self.step1()
}
}
}
关键是动画的各个阶段永远不会在两个视图之间失去同步,因为每个阶段都涉及两个视图并遵循前一个阶段。所以我很确定你可以采用这种方法来适应你的动画。
我喜欢@ matt的答案并且总是欣赏他们的输入但是因为我试图使用CAAnimation(特别是我想使用CAKeyframeAnimation),我最终使用CATransaction.begin()
和CATransaction.setCompletionBlock
嵌套两个CATransactions以在另一个结束时开始一个动画,然后以递归方式重复调用该函数。