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
暂停,动画的内部计数器继续,并在动画应完成时调用完成块。