首页 文章

有没有办法观察UIViewPropertyAnimator中fractionComplete的变化

提问于
浏览
17

我一直在关注iOS 10中非常酷的新版 UIViewPropertyAnimator 类 . 它可以让你 easily 执行暂停,恢复和反向飞行UIView动画等操作 . 过去,您必须操纵系统创建的基础CAAnimations才能使用UIView动画执行此操作 .

新的 UIViewPropertyAnimator 类有一个属性 fractionComplete . 它从0.0(动画开始)到1.0(动画结束)不等 . 如果更改了值,则可以从开始到结束动画"scrub" .

我在Github上有一个名为KeyframeViewAnimations的演示项目,它允许你使用滑块来使用相当神秘的CAAnimation技巧来回擦洗UIView和CAAnimations . 当动画运行时,滑块从头到尾移动以显示动画的进度 . 该项目是在Swift发布之前用Objective-C编写的,但Objective-C或Swift中的底层技术是相同的 .

我决定使用 UIViewPropertyAnimator 创建一个等效项目 . 有一些怪癖,但它有's fairly straightforward. One thing I could not figure out how to do cleanly was to observe the progress of the animation' s fractionComplete 属性,这样我就可以在动画进行时更新滑块 . 我尝试在 fractionComplete 属性上设置KVO(键值观察),但在动画完成之前它不会触发KVO通知 .

我最终做的是设置一个在很小的时间间隔内运行的计时器,并重复查询 UIViewPropertyAnimatorfractionComplete 属性,并在滑块前进时更新它 . 它有效,但它不是一种非常干净的做事方式 . 如果有办法获得有关动画进度的通知会好得多 .

我希望有一些我想念的东西 .

您可以在此链接上看到基于 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 计时器而不是使用vanilla Timer(NSTimer),但我更好的方法是'm hoping there' .

1 回答

  • 0

    您是否尝试了子类化UIViewPropertyAnimator然后重写fractionComplete属性?

    class MyPropertyAnimator : UIViewPropertyAnimator {
        override var fractionComplete: CGFloat {
            didSet {
                print("didSetFraction")
            }
        }
    }
    

相关问题