CADisplayLink是什么
根据Apple的doc:
A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the refresh rate of the display.
比起NSTimer,CADisplayLink可以确保系统渲染每一帧的时候我们的方法都被调用,从而保证了动画的流畅性。
Demo
我们希望在animate一个view的时候给它加上果冻效果:

我们会把所有的逻辑都封装到一个BlockView里,在这个view里首先申明一个property:
|
1
|
@property (strong, nonatomic) CADisplayLink *displayLink; |
在动画开始的时候,初始化displayLink,指定tick方法:
|
1
2
3
4
5
6
7
8
|
- (void)startAnimation{ if (self.displayLink == nil) { self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)]; [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; }} |
动画结束的时候invalidate displayLink:
|
1
2
3
4
5
|
- (void)completeAnimation{ [self.displayLink invalidate]; self.displayLink = nil;} |
每个tick中,我们需要根据当前的位置重绘边缘,所以只需调用setNeedsDisplay即可:
|
1
2
3
4
|
- (void)tick:(CADisplayLink *)displayLink{ [self setNeedsDisplay];} |
在drawRect中,我们计算当前动画的progress,然后进行绘制。需要注意的是,我们需要通过self.layer.presentationLayer来获取动画过程中的位置信息。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
- (void)drawRect:(CGRect)rect{ CALayer *layer = self.layer.presentationLayer; CGFloat progress = 1 - (layer.position.y - self.to) / (self.from - self.to); CGFloat height = CGRectGetHeight(rect); CGFloat deltaHeight = height / 2 * (0.5 - fabs(progress - 0.5)); CGPoint topLeft = CGPointMake(0, deltaHeight); CGPoint topRight = CGPointMake(CGRectGetWidth(rect), deltaHeight); CGPoint bottomLeft = CGPointMake(0, height); CGPoint bottomRight = CGPointMake(CGRectGetWidth(rect), height); UIBezierPath* path = [UIBezierPath bezierPath]; [[UIColor blueColor] setFill]; [path moveToPoint:topLeft]; [path addQuadCurveToPoint:topRight controlPoint:CGPointMake(CGRectGetMidX(rect), 0)]; [path addLineToPoint:bottomRight]; [path addQuadCurveToPoint:bottomLeft controlPoint:CGPointMake(CGRectGetMidX(rect), height - deltaHeight)]; [path closePath]; [path fill];} |
最后,我们只需要这样animate这个BlockView:
|
1
2
3
4
5
6
|
[self.blockView startAnimationFrom:from to:to]; [UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.85 initialSpringVelocity:0 options:0 animations:^{ self.blockView.center = CGPointMake(self.blockView.center.x, to); } completion:^(BOOL finished) { [self.blockView completeAnimation]; }]; |
本文介绍如何使用CADisplayLink实现流畅的果冻效果动画。相较于NSTimer,CADisplayLink能确保动画每一帧都能准确同步屏幕刷新率,提高动画流畅度。文章通过具体示例展示了如何在iOS应用中实现这一效果。
1329

被折叠的 条评论
为什么被折叠?



