斯威夫特:重复的连续CABasicAnimations

问题描述 投票:0回答:2

目标:

  • 第一个动画运行持续时间为1.0
  • 在1.0,第二个动画运行(而第一个动画自动反转回其起点)
  • 在2.0,第一个动画回到起点,第二个动画完成,第一个动画重复
  • 在3.0,第二个动画在第一个动画结束第二次运行时运行

我的代码:

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

这两个动画有时会匹配,但不会在每个构建中匹配。是否有一种更加可靠的方式来启动第二个动画,以便在初始动画的第一个完成动画结束时开始?这样他们就可以从那一点开始同步。谢谢你的帮助!

ios swift animation timing caanimation
2个回答
0
投票

我对我们想要实现的目标有点不清楚,但我的感觉是,我们有两种观点,重复动画需要协调。为了演示如何做到这一点的一个例子,我选择让两个动画都放大,然后缩小:

enter image description here

这里的动画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()
        }
    }
}

关键是动画的各个阶段永远不会在两个视图之间失去同步,因为每个阶段都涉及两个视图并遵循前一个阶段。所以我很确定你可以采用这种方法来适应你的动画。


0
投票

我喜欢@ matt的答案并且总是欣赏他们的输入但是因为我试图使用CAAnimation(特别是我想使用CAKeyframeAnimation),我最终使用CATransaction.begin()CATransaction.setCompletionBlock嵌套两个CATransactions以在另一个结束时开始一个动画,然后以递归方式重复调用该函数。

CATransaction documentation

© www.soinside.com 2019 - 2024. All rights reserved.