我有以下情况:我有一个圆圈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)
}
})
}
}
但它不能正常工作,它会跳过几点,并减慢动画
答案 0 :(得分:0)
我能够通过使用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并设置上一个 UIViewPropertyAnimator的completionHandler
来调用startAnimating()
在新的。因此,在动画进行过程中,链条会实时扩展。
根据您的要求,每个动画的duration
是根据我们前往下一个点的距离来计算的,因此速率是恒定的。我故意选择一个缓慢的恒定速率来使行为清楚。
结果是,即使除了第一个点之外的所有点都已经进行动画,我们也会以恒定速率通过所有点。为了澄清发生了什么,我让每个完成处理程序也将视图闪烁为红色,以便您知道下一个动画何时开始。因此,我们清楚地看到每个动画的开始时间与上一个动画的目标点完全一致 - 我认为这就是你想要做的事情。