如何动态地将动画添加到队列中

Posted

技术标签:

【中文标题】如何动态地将动画添加到队列中【英文标题】:How to add animation to a queue dynamically 【发布时间】:2018-04-17 17:09:46 【问题描述】:

我有以下情况:我有一个圆形 uiview 对象,例如,我每 1 秒得到一个新点。我对从 uiview 的当前位置到新点的移动进行动画处理,动画持续时间取决于距离,因此动画持续时间可能是 500 毫秒或超过 3 秒。所以请考虑以下手绘(通过 ipad 抱歉)图表:

在“A”的情况下,如果我有相同方向的点,我的动画顺序没有问题。

但如果是“B”,那是我的问题;如果我将圆从第 3 点动画到第 4 点,它需要 5 秒,并且在 1 秒后我收到第 5 点,一个新的动画从第 4 点开始到第 5 点,结果动画将类似于红线.

我需要一种方法来添加像队列这样的添加动画,并且搜索了很多都没有结果。

我目前的做法是这样的:

var animationPoints = [CGPoint]()
var isAnimating = false

func animate(nextPoint) 

    animationPoints.append(nextPoint)

    if !isAnimating 
        isAnimating = true

        let p = animationPoints.first
        animationPoints.removeFirst

        UIView.animate ( completed in

            isAnimating = false

            if animationPoints.count > 0 
                animate(animationPoints.first)
            
        )

    

但它不能正常工作,它会跳过几个点,并减慢动画速度

【问题讨论】:

怎么调用animate()方法,是不是用for循环 我在获得新点时调用该方法,但如果它已经动画,我在 Uiview.animate 完成处理程序中调用它 这是你完整的动画代码吗?看起来很奇怪,因为您没有控制标志 isAnimating 也没有显示动画参数让我们重现。 哦,我忘了在有问题的代码中添加 isAnimating 标志控件,请检查编辑。 Animate 参数是 CGPoint 类型,虽然它是半伪代码。 您的伪代码似乎是正确的方法。如果您需要帮助调试它,您需要发布您的真实代码。 【参考方案1】:

我能够通过使用 UIViewPropertyAnimator 对象队列来实现您的要求,每个对象都通过前一个的完成处理程序链接到前一个对象,就像您的伪代码中所建议的那样。我这样做的原因是可以随时向 UIViewPropertyAnimator 对象添加完成处理程序,包括在动画师开始制作动画之后。

为了测试,我人为的安排了一系列点实时间隔到达:

var points = [
    CGPoint(x: 60, y: 50),
    CGPoint(x: 100, y: 50),
    CGPoint(x: 150, y: 50),
    CGPoint(x: 150, y: 100),
    CGPoint(x: 250, y: 100)
]
@IBAction func doButton(_ sender: Any) 
    func nextPoint() 
        self.animateToPoint(points.removeFirst())
        if !points.isEmpty 
            delay(0.25) 
                nextPoint()
            
        
    
    nextPoint()

每次到达一个点(即每次调用self.animateToPoint),我都会创建一个新的UIViewPropertyAnimator 并设置previous UIViewPropertyAnimator 的completionHandler 来调用新的startAnimating()。因此,在动画进行时,链条会实时延长。

按照你的要求,每个动画的duration是根据我们到下一个点的距离来计算的,这样速率是恒定的。我特意选择了一个缓慢的恒定速率以使行为清晰。

结果是,即使动画在除第一个点之外的所有点到达时已经在进行,我们仍以恒定速率通过所有点。为了澄清发生了什么,我让每个完成处理程序也将视图闪烁红色,以便您知道下一个动画何时开始。因此,我们清楚地看到,每个动画都是在到达前一个动画的目标点时开始的——我认为这就是你所说的你想做的。

【讨论】:

问题是我事先不知道点,所以我需要通过增强逻辑来动态平滑动画。

以上是关于如何动态地将动画添加到队列中的主要内容,如果未能解决你的问题,请参考以下文章

如何平滑地将 CSS 动画恢复到当前状态?

如何做动画水印 如何给视频添加动态水印

将动态文本动画添加到 nivo 滑块

如何在视图和动态壁纸中适合 GIF 动画的内容?

以可变帧大小动态地将精灵表切割成单独的位图

如何动态地将组件作为子组件添加到指令中?