swift animate Keyframes with RelativeStartTime 不起作用

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

我想实现一个动画:每个单元格 rightImage 首先移动,在 rightImage 移动后,背景图像(这是一个 gif)开始动画。但是,移动动画和 gif startAnimating 总是同时开始。就像下面的演示:

这是打印移动时间戳和动画时间戳的调试日志:

<<< start index:  0
>>> start transfrom 2023-04-04 10:32:39
>>> start animating 2023-04-04 10:32:39
<<< start index:  1
>>> start transfrom 2023-04-04 10:32:43
>>> start animating 2023-04-04 10:32:43
<<< start index:  2
>>> start transfrom 2023-04-04 10:32:47
>>> start animating 2023-04-04 10:32:47

这是我的动画代码:

func startMoving() {
        let duration: Double = 4
        UIView.animateKeyframes(withDuration: duration, delay: 0, options: [.calculationModeLinear], animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.7/duration, animations: {
                print(">>> start transfrom")
                self.frontImageView.transform = CGAffineTransform(translationX: -20, y: 0)
            })
            UIView.addKeyframe(withRelativeStartTime: 0.7/duration, relativeDuration: 1.5/duration, animations: {
                print(">>> start animating")
                self.backgroundImageView.startAnimating()
            })
        }, completion: { _ in
            self.backgroundImageView.stopAnimating()
        })
    }
swift uicollectionview uikit core-animation cakeyframeanimation
1个回答
0
投票

几件事...

1 - 您错误地使用了相对开始时间和相对持续时间 2 - 关键帧动画并不像你想象的那样工作

相对时间是持续时间的百分比

如果您希望第一个关键帧立即开始,并运行总持续时间的 70%,它应该如下所示:

UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.7, animations: {

并且您希望第二个关键帧在第一个动画结束时开始(因此,从开始开始的 70%),然后运行剩余部分:

UIView.addKeyframe(withRelativeStartTime: 0.7, relativeDuration: 0.3, animations: {

所以,让我们更改计时参数,并添加更多

print()
语句:

func startMoving() {
    let duration: Double = 4
    
    UIView.animateKeyframes(withDuration: duration, delay: 0, options: [.calculationModeLinear], animations: {
        
        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.7, animations: {
            print(">>> start transfrom")
            self.frontImageView.transform = CGAffineTransform(translationX: -20, y: 0)
        })
        UIView.addKeyframe(withRelativeStartTime: 0.7, relativeDuration: 0.3, animations: {
            print(">>> start animating")
            self.backgroundImageView.startAnimating()
        })
        
    }, completion: { _ in
        print(">>> completion")
        self.backgroundImageView.stopAnimating()
    })
    
    print(">>> end of startMoving()")
}

您将在调试控制台中看到的是立即

>>> start transfrom
>>> start animating
>>> end of startMoving()

在 4 秒结束时:

>>> completion

但是,您仍然会看到动画从零开始。

关键帧动画 not 等待执行代码。在

UIView.animateKeyframes
块内,UIKit 立即分析所有
addKeyFrame
片段,然后“播放动画”

这就是为什么生成的动画会根据

KeyFrameAnimationOptions

.calulationMode...
 值)看起来不同的原因。

逻辑上,我们

认为这一行:self.backgroundImageView.startAnimating()

在总持续时间的70%时执行。实际上,它在UIKit构建动画时执行,这就是为什么你的图像视图动画从开始开始.

如果你想让“前”视图滑过,然后

然后启动图像视图动画,你需要播放滑过动画并在完成后启动图像视图动画。

沿着这些线的东西:

func startMoving() { let duration: Double = 4.0 * 0.7 UIView.animate(withDuration: duration, animations: { print(">>> start transfrom") self.frontImageView.transform = CGAffineTransform(translationX: -20, y: 0) }, completion: { _ in print(">>> start animating") // maybe set imageView animation properties... self.backgroundImageView.animationRepeatCount = 1 self.backgroundImageView.animationDuration = 1.0 // 1-second to cycle through all images self.backgroundImageView.startAnimating() }) print(">>> end of startMoving()") }
    
© www.soinside.com 2019 - 2024. All rights reserved.