Farlanki

使用CADisplayLink观察动画

字数统计: 358阅读时长: 1 min
2016/06/07 Share

我们经常使用CABasicAnimation实现动画效果,如果要观察动画实现时候的值,应该怎么实现呢?
1.使用KVO,提示被观察者在observer被释放之前就释放了.
2.使用NSTimer,NSTimer有间隔不稳定的问题.
3.使用CADisplayLink
CADisplayLink是一个定时器.和NSTimer不同的是,它是和屏幕的刷新率相同的,比较准确.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var animation = CASpringAnimation()
animation.keyPath = "position.y"
animation.fromValue = animatingItem!.layer.position.y - itemSpace - itemSize
animation.toValue = animatingItem!.layer.position.y
animation.duration = animation.settlingDuration
animation.mass = 1
animation.stiffness = 200
animation.damping = 10
animation.initialVelocity = 0
animatingItem?.layer.hidden = false
displayLink = CADisplayLink(target: self, selector: "printItemPosition")
displayLink!.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
CATransaction .begin()
CATransaction.setCompletionBlock { [weak self] in
self!.displayLink!.paused = true
self!.displayLink!.invalidate()
}
animatingItem?.layer.addAnimation(animation, forKey: "basic")
CATransaction.commit()
1
2
3
func printItemPosition(){
print(self.animatingItem!.layer.presentationLayer()!.position.y)
}

使用CADisplayLink精确控制动画

以下这个动画效果为:当一个item的位置下降到一定位置时,触发下一个item的动画效果.
我的第一个想法是使用UIView的addAnimation方法,并且设置completion,但是发现CASpringAnimation是layer层的,和UIVew的addAnimation方法不兼容.接下来想到使用CATransaction的setCompletionBlock方法,发现和设想中的效果有偏差:CASpringAnimation的持续时间包括缓慢停止的时间,这样设置并不能达到流畅下落的效果.最后尝试使用CADisplayLink,观察正在下落的item的presentationLayer的position,当item到达一定的position,触发下一个item的动画.
代码见github

CATALOG
  1. 1. 使用CADisplayLink精确控制动画