我一直在关注UIViewPropertyAnimator
iOS 10 中非常酷的新类。它可以让您轻松地执行暂停、恢复和反转飞行中的 UIView 动画等操作。过去,您必须操作系统创建的底层 CAAnimations 才能使用 UIView 动画执行此操作。
新UIViewPropertyAnimator
类有一个属性fractionComplete
。它从 0.0(动画开始)到 1.0(动画结束)不等。如果更改该值,则可以从头到尾“擦洗”动画。
我在 Github 上有一个名为KeyframeViewAnimations的演示项目,它允许您使用滑块来使用相当神秘的 CAAnimation 技巧来回擦洗 UIView 和 CAAnimations。随着动画的运行,滑块从头到尾移动以显示动画的进度。该项目是在 Swift 发布之前用 Objective-C 编写的,但底层技术在 Objective-C 或 Swift 中是相同的。
我决定使用UIViewPropertyAnimator
. 有一些怪癖,但它相当简单。我无法弄清楚如何干净地做的一件事是观察动画fractionComplete
属性的进度,以便我可以随着动画的进行更新滑块。我尝试在属性上设置 KVO(键值观察)fractionComplete
,但在动画完成之前它不会触发 KVO 通知。
我最终做的是设置一个以非常小的间隔运行的计时器,并重复查询UIViewPropertyAnimator
' 的属性并随着滑块的进行更新滑块。fractionComplete
它有效,但它不是一种非常干净的做事方式。如果有办法获得有关动画进度的通知会更好。
我希望我缺少一些东西。
您可以UIViewPropertyAnimator
在 Github 上的这个链接中看到基于项目的项目:UIViewPropertyAnimator-test。
从动画师那里获取进度值的代码是这样的代码:
func startTimer(_ start: Bool) {
if start {
timer = Timer.scheduledTimer(withTimeInterval: 0.02,
repeats: true) {
timer in
var value = Float(self.viewAnimator.fractionComplete)
if self.animatingBackwards {
value = 1 - value
}
self.animationSlider.value = value
}
}
else {
self.timer?.invalidate()
}
}
我可能应该将上面的代码转换为使用CADisplayLink
计时器而不是普通计时器(NSTimer),但我希望有更好的方法。