如何动态地将动画添加到队列中
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
是根据我们到下一个点的距离来计算的,这样速率是恒定的。我特意选择了一个缓慢的恒定速率以使行为清晰。
结果是,即使动画在除第一个点之外的所有点到达时已经在进行,我们仍以恒定速率通过所有点。为了澄清发生了什么,我让每个完成处理程序也将视图闪烁红色,以便您知道下一个动画何时开始。因此,我们清楚地看到,每个动画都是在到达前一个动画的目标点时开始的——我认为这就是你所说的你想做的。
【讨论】:
问题是我事先不知道点,所以我需要通过增强逻辑来动态平滑动画。以上是关于如何动态地将动画添加到队列中的主要内容,如果未能解决你的问题,请参考以下文章