老谭笔记

OSX的动画实现(二)——扩展CALayer支持的动画

在上一篇文章中已经介绍了如何使用CABasicAnimation来实现一个动画,但在实际的编码中我们会发现并非所有的CALayer都能够使用CABaseAnimation来做动画,尤其是我们自定义的CALayer子类所拥有的扩展属性,今天我们就来尝试让这些属性也可以做动画(同样适用于iOS开发)。

要让指定的属性也支持动画,我们需要重写实现CALayer的这三个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//根据一个layer复制出另一个layer(构造动画中的帧)
- (id)initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self)
{
if ([layer isKindOfClass:[THSectorLayer class]])
{
self.startAngle = [(THSectorLayer *)layer startAngle];
self.endAngle = [(THSectorLayer *)layer endAngle];
self.bgColor = [(THSectorLayer *)layer bgColor];
self.fillColor = [(THSectorLayer *)layer fillColor];
self.progress = [(THSectorLayer *)layer progress];
self.imgRef = [(THSectorLayer *)layer imgRef];
}
}
return self;
}
//根据属性名称返回对应的CAAnimation对象
- (id)actionForKey:(NSString *)key
{
if ([key isEqualToString:@"progress"])
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"progress"];
anim.fromValue = [[self presentationLayer] valueForKey:key];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
anim.duration = 0.2;
return anim;
}
return [super actionForKey:key];
}
//根据属性名称返回是否需要做动画
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([key isEqualToString:@"progress"] || [key isEqualToString:@"startAngle"] || [key isEqualToString:@"endAngle"])
{
return YES;
}
return [super needsDisplayForKey:key];
}

示例代码下载:McAnimation_CABaseAnimation_Extend

该示例代码是一个带指针的扇形进度条控件,效果如下:

animation_11