我正在使用UIViewPropertyAnimator
制作小型contentOffset
动画。
为了使视图控制器保持精简,我在UIScrollView
子类中有要进行动画处理的动画代码。我最初是在UIView.animate
块中制作动画的,但是我注意到当视图消失时(即另一个视图被推到视图顶部),动画跳到了结尾,因此我尝试在其中暂停动画。另外,我想通过不必要的动画调用来减少CPU负载。
var animator: UIViewPropertyAnimator?
...
func showAnimation() {
...
if animator == nil {
animator = UIViewPropertyAnimator(duration: duration, curve: .linear, animations: { [unowned self] in
self.contentOffset = endPoint
})
animator?.addCompletion { [unowned self] (position) in
if position == .end {
self.afterAnimation()
print("completion called")
}
}
}
}
func pauseAnimation() {
if animator?.state == .active {
animator?.pauseAnimation()
}
print("paused animation")
}
方法afterAnimation()
仅确定是否再次调用showAnimation()
。
在我的视图控制器中,我基本上具有以下内容:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myScrollView.showAnimation()
}
override func viewWillDisappear(_ animated: Bool) {
viewWillDisappear(animated)
myScrollView.pauseAnimation()
}
现在,只要用户在另一个屏幕上停留的时间不长,此方法就可以很好地工作。 例如,如果用户调出设置屏幕(将其推到 导航堆栈),如预期的那样,调用了pause方法。如果用户留下 在该屏幕中的时间过长,则动画师的完成方法将被调用,即使 动画未完成。用户再次关闭设置屏幕后, 动画被冻结,无法继续。
我也尝试过
animator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: duration, delay: 0, options: .curveLinear, animations: { [unowned self] in
self.contentOffset = endPoint
print("starting animation")
}) { [unowned self] _ in
self.afterAnimation()
print("completion called")
}
,但结果相同。片刻之后,完成块被调用。
如何最好地解决此问题?谢谢!
编辑:通过不同的打印语句,我逐渐有了一个想法,即使animator
暂停时,动画的内部计数器也会继续运行,并在动画结束时调用完成块。