自定义CALayer动画

来源:互联网 发布:北方工业公司 知乎 编辑:程序博客网 时间:2024/05/16 19:46

    当我们需要区实现一个layer的时候,并且需要为其添加一个属性动画的时候,我们需要有这么几步操作:

首先,我们需要去继承一个CALayer类,同时实现以下的几个方法:

+ (BOOL)needsDisplayForKey:(NSString *)key

方法来判断当前属性改变是否需要重新绘制。如果想实现自定义动画就需要重载这个方法,当key等于扩展属性时return yes即可;

这句话什么意思?这里在layer中有这么一个方法 - (void)drawInContext:(CGContextRef)ctx  ,这个方法就类似于我们去写一个自定义的View,而在View中需要重写drawRect方法一样,用来实现绘图。而以上方法也正是调用这个方法去绘图。

我们先来创建一个CircleLayer类:

#import <QuartzCore/QuartzCore.h>

#import <CoreGraphics/CoreGraphics.h>

#import <UIKit/UIKit.h>

@interface CircleLayer :CALayer

@property(nonatomic ,assign)CGFloat progress;

@end


在.m中重载一下这两个方法:

- (void)drawInContext:(CGContextRef)ctx

{

    NSLog(@"%s",__FUNCTION__);

    

    CGContextSetLineWidth(ctx,5.f);

    CGContextSetStrokeColorWithColor(ctx, [UIColorblackColor].CGColor);

    CGContextAddArc(ctx,CGRectGetWidth(self.bounds)/2.,CGRectGetHeight(self.bounds)/2.,CGRectGetWidth(self.bounds)/2.6M_PI_2 * 3,M_PI_2*3+M_PI*2*self.progress,0);

    CGContextStrokePath(ctx);

    

}



+ (BOOL)needsDisplayForKey:(NSString *)key{

   NSLog(@"__%s__ %@",__FUNCTION__,key);

    return [keyisEqualToString:@"progress"]?YES:[superneedsDisplayForKey:key];

}


稍微说明下:drawInContext 绘制一个圆圈,根据progress绘制出实际的弧度,progress正是我们的自定义属性。needsDisplayForKey 自然是让progress自动调用setNeedsDisplay。需要注意的是,我们也可以直接去调用setNeedsDisplay去令其直接画图。

定义好我们的自定义layer后,只要为其添加动画即可:

 CABasicAnimation* animat = [CABasicAnimationanimationWithKeyPath:@"progress"];

    animat.duration =6.f;

    animat.fromValue = [NSNumbernumberWithFloat:[(CircleLayer*)[layerpresentationLayer]progress]];

    animat.toValue = [NSNumbernumberWithFloat:1.0f];

    animat.timingFunction = [CAMediaTimingFunctionfunctionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    [layeraddAnimation:animatforKey:@"gogogo"];


以上便是实现动画的核心内容,具体详细的内容可以研究下一下帖子:

http://blog.csdn.net/growinggiant/article/details/42493329

http://www.jianshu.com/p/78e1b416e56a