CoreAnimation

今天抽空大致介绍iOS开发中常见动画的使用,及注意点:
下面以一张图片总结一下iOS开发中常用动画,

流程.png

CALayer:隐式动画

CATransaction :NSObject(区分下面的CATransition,他是继承CATran)

[CATransaction begin];
 
[CATransaction setDisableActions:!enableAnimation.isOn];

[CATransaction setAnimationDuration:animationDuration.value];

[_layer setCornerRadius:[_layer cornerRadius]==0?30:0];

[_layer setBorderWidth:[_layer borderWidth]==0?5:0];

[_layer setBorderColor:[UIColor redColor].CGColor];

[CATransaction commit];

常用方法

  • (void)begin;
  • (void)commit;
  • (void)flush;
  • (void)lock;
  • (void)unlock;
隐式动画.png
[UIView beginAnimations:@"animationID" context:nil];

[UIView setAnimationDuration:animationDuration.value];

[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

[UIView setAnimationRepeatAutoreverses:enableAnimation.isOn];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:image cache:YES];

[UIView commitAnimations];

常用方法:

setAnimationDuration

+ (void)beginAnimations:(NSString *)animationID context:(void *)context;  
+ (void)commitAnimations; 


+ (void)setAnimationDuration:(NSTimeInterval)duration;              // default = 0.2
+ (void)setAnimationDelay:(NSTimeInterval)delay;    // default=now ([NSDate date])
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;              // default = UIViewAnimationCurveEaseInOut
+ (void)setAnimationRepeatCount:(float)repeatCount;    
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache;  // current limitation - only one per begin/commit block

Block动画:

[UIView animateWithDuration:animationDuration.value delay:.5 options:UIViewAnimationOptionCurveEaseOut animations:^(void){

[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:image cache:YES];
            } completion:^(BOOL finish){
                animationDurationLabel.text = @"动画结束";
            }];

常用方法

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0

UIViewKeyframeAnimations分类(非正式协议):

+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation

三:核心动画

![核心动画.png](http://upload-images.jianshu.io/upload_images/652450-9a4b98253c83f877.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

核心动画中最基本的属性与方法

+ (instancetype)animation;
+ (id)defaultValueForKey:(NSString *)key;
- (BOOL)shouldArchiveValueForKey:(NSString *)key;
@property(strong) CAMediaTimingFunction *timingFunction;
@property(strong) id delegate;
 

非正式协议:

- (void)animationDidStart:(CAAnimation *)anim;
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
 @property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
下面也是在官方文档中关于核心动画的一段话

CAAnimation is an abstract animation class. It provides the basic support for the CAMediaTiming and CAAction protocols. To animate Core Animation layers or Scene Kit objects, create instances of the concrete subclasses CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, or CATransition.

CATransition(转场动画)

继承自:CAAnimation

CATransition *transtion = [CATransition animation];

[transtion setStartProgress:.2];

[transtion setEndProgress:.8];

transtion.duration = animationDuration.value;

[transtion setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[transtion setType:@"rippleEffect"];

[transtion setSubtype:kCATransitionFromTop];

[image.layer addAnimation:transtion forKey:@"transtionKey"];
转场动画.png

常用属性

@property(copy) NSArray *animations;
@property float startProgress;
@property float endProgress;
@property(strong) id filter;
duration:设置动画时间
type:subtype:typetimingFunction ,,(),

转场类型type:

Fade = 1,                   //淡入淡出
Push,                       //推挤
Reveal,                     //揭开
MoveIn,                     //覆盖
Cube,                       //立方体
SuckEffect,                 //吮吸(水滴)
OglFlip,                    //翻转
RippleEffect,               //波纹

(默认以父类为参照,所以一般我们使用一个和子控件一样大的父控件来修改这个效果)
PageCurl, //翻页
PageUnCurl, //反翻页
CameraIrisHollowOpen, //开镜头
CameraIrisHollowClose, //关镜头
CurlDown, //下翻页
CurlUp, //上翻页
FlipFromLeft, //左翻转
FlipFromRight, //右翻转
转场子类型subtype:

kCAMediaTimingFunctionLinear 线性即匀速
kCAMediaTimingFunctionEaseIn 先慢后快
kCAMediaTimingFunctionEaseOut 先快后慢
kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
kCAMediaTimingFunctionDefault 实际效果是动画中间比较快

注意:转场动画与转场代码必须写在一起,否则无效

CAPropertyAnimation动画

CAPropertyAnimation(属性动画),是后面两个动画的父类

继承自:CAAnimation

CAPropertyAnimation *pro = [CAPropertyAnimation animation];

pro.additive = YES;

pro.cumulative = YES;

pro.valueFunction = kCAValueFunctionScaleX;

[image.layer addAnimation:pro forKey:AnimationKey]

常用属性

  • (instancetype)animationWithKeyPath:(NSString *)path;
    @property(copy) NSString *keyPath;
    @property(getter=isAdditive) BOOL additive;
    @property(getter=isCumulative) BOOL cumulative;
    @property(strong) CAValueFunction *valueFunction;

CABasicAnimation(基本动画)

继承自;CAPropertyAnimation

CABasicAnimation *basic = [CABasicAnimation     animationWithKeyPath:@"transform.scale"];

[basic setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];

[basic setFromValue:[NSNumber numberWithFloat:1]];

[basic setToValue:[NSNumber numberWithFloat:.3]];

[basic setDuration:animationDuration.value];

[basic setDelegate:self];

[image.layer addAnimation:basic forKey:AnimationKey];

基本属性

@property(strong) id fromValue;
@property(strong) id toValue;
@property(strong) id byValue;

基本动画.png

CAKeyframeAnimation(关键帧)

继承自;CAPropertyAnimation

1):values->

CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"borderWidth"];

keyframe.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],

[NSNumber numberWithFloat:5],

[NSNumber numberWithFloat:10],

[NSNumber numberWithFloat:15],nil];

// keyframe.values = @[@12, @-12, @12];

keyframe.repeatCount = MAXFLOAT;

keyframe.autoreverses = enableAnimation.isOn;

keyframe.duration = animationDuration.value;

[image.layer addAnimation:keyframe forKey:AnimationKey];

2):paths->

UIBezierPath *path = [UIBezierPath bezierPath];

       // [path moveToPoint:image.frame.origin];

[path moveToPoint:CGPointMake(image.frame.origin.x + image.frame.size.width/2, image.frame.origin.y + image.frame.size.height/2)];

[path addLineToPoint:CGPointMake(image.frame.origin.x + image.frame.size.width/2,400)];

[path addLineToPoint:CGPointMake(20, 400)];

CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"position"];

keyframe.path = path.CGPath;

keyframe.duration = animationDuration.value;

[image.layer addAnimation:keyframe forKey:AnimationKey];
关键帧-抖动.png

常见属性

@property(copy) NSArray *values;
@property CGPathRef path;
@property(copy) NSArray *keyTimes;
@property(copy) NSArray *timingFunctions;
@property(copy) NSString *calculationMode;
@property(copy) NSArray *tensionValues;
@property(copy) NSArray *continuityValues;
@property(copy) NSArray *biasValues;
@property(copy) NSString *rotationMode;

CAAnimationGroup(动画组)

继承自:CAAnimation

CAAnimationGroup *group = [CAAnimationGroup animation];

CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

[basic setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];

[basic setFromValue:[NSNumber numberWithFloat:1]];

[basic setToValue:[NSNumber numberWithFloat:.3]];

CAKeyframeAnimation *keyframe = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.x"];

keyframe.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:M_PI], nil];

[group setDuration:animationDuration.value];

[group setAnimations:[NSArray arrayWithObjects:basic,keyframe, nil]];

[image.layer addAnimation:group forKey:AnimationKey];

常见属性

@property(copy) NSArray *animations;
@property(copy) NSString *fillMode;
fillMode

kCAFillModeForwards
kCAFillModeBackwards
kCAFillModeBoth
kCAFillModeRemoved

UIView动画与核心动画的区别,及使用注意的地方:

1:核心动画的一切都是假象,并不会真实的修改layer对应的属性
2:UIView必须修改真实属性的值

使用-》
只要不需要与用户交互就使用核心动画,如果需要与用户交互就使用UIView动画
核心动画的使用场景:转场(核心动画包装的转场动画足够强大)

3D动画

下面来电更酷的3D动画(结合以上技术)

[UIView animateWithDuration:animationDuration.value animations:^{

                [UIView setAnimationRepeatCount:MAXFLOAT];

                [UIView setAnimationRepeatAutoreverses:enableAnimation.isOn];

                CATransform3D transform = CATransform3DMakeTranslation(0, -150, 0);

                CATransform3D trans = CATransform3DScale(transform, 1.5, 1.5, 10);

                [label.layer setTransform:trans];

            } completion:^(BOOL finished) {

                animationDurationLabel.text = @"finished";

            }];

CABasicAnimation

CABasicAnimation *basic = [CABasicAnimation 

animationWithKeyPath:@"transform.scale"];

[basic setDuration:animationDuration.value];

[basic setRepeatCount:MAXFLOAT];

[basic setAutoreverses:enableAnimation.isOn];

NSValue *valueForm = [NSValue 

valueWithCATransform3D:CATransform3DIdentity];

CATransform3D transTo = CATransform3DMakeScale(.5, .5, 0);

NSValue *valueTo = [NSValue valueWithCATransform3D:transTo];

[basic setFromValue:valueForm];

[basic setToValue:valueTo];

[image.layer addAnimation:basic forKey:AnimationKey];

CAKeyframeAnimation

CAKeyframeAnimation *keyframe = [CAKeyframeAnimation 

animationWithKeyPath:@"transform.scale"];

[keyframe setRepeatCount:MAXFLOAT];

[keyframe setDuration:animationDuration.value];

[keyframe setAutoreverses:enableAnimation.isOn];

CATransform3D transForm = CATransform3DIdentity;

CATransform3D transTo = CATransform3DMakeScale(.5, .5, 0);

NSValue *valueForm = [NSValue 

valueWithCATransform3D:transForm];

NSValue *valueTo = [NSValue valueWithCATransform3D:transTo];

[keyframe setValues:[NSArray 

arrayWithObjects:valueTo,valueForm,nil]];

[image.layer addAnimation:keyframe forKey:AnimationKey];

CABasicAnimation

CABasicAnimation *basic = [CABasicAnimation 

animationWithKeyPath:@"transform"];

[basic setRepeatCount:MAXFLOAT];

[basic setDuration:animationDuration.value];

[basic setAutoreverses:enableAnimation.isOn];

NSValue *valueForm = [NSValue 

valueWithCATransform3D:CATransform3DIdentity];

CGAffineTransform affine = CGAffineTransformMakeTranslation(0, 
-150);

CATransform3D t = CATransform3DMakeAffineTransform(affine);

CATransform3D trans = CATransform3DScale(t, 1.5, 1.5, 10);

NSValue *valueTo = [NSValue valueWithCATransform3D:trans];

[basic setFromValue:valueForm];

[basic setToValue:valueTo];

[label.layer addAnimation:basic forKey:AnimationKey];

3D弹出和隐藏动画效果:

    //使用关键帧-3D动画实现按钮的弹出效果
CAKeyframeAnimation *popAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];

popAnimation.duration = 0.4;

popAnimation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.01f, 0.01f, 1.0f)],

[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.0f)],

[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9f, 0.9f, 1.0f)],

[NSValue valueWithCATransform3D:CATransform3DIdentity]];

popAnimation.keyTimes = @[@0.2f, @0.5f, @0.75f, @1.0f];

popAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[self.layer addAnimation:popAnimation forKey:nil];

//使用关键帧动画实现隐藏效果

CAKeyframeAnimation *hideAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];

hideAnimation.duration = 0.4;

hideAnimation.values = @[[NSValue 

valueWithCATransform3D:CATransform3DMakeScale(1.1f, 1.1f, 1.0f)],

[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0f, 1.0f, 1.0f)],

[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.00f, 0.00f, 0.00f)]];

hideAnimation.keyTimes = @[@0.2f, @0.5f, @0.75f];

hideAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut],

[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

hideAnimation.delegate = self;

[self.layer addAnimation:hideAnimation forKey:nil];

注意:核心动画中有一个协议需要注意的:CAMediaTiming

下面是协议对应的一些属性(方法)

@property CFTimeInterval beginTime;
@property CFTimeInterval duration;
@property float speed;
@property CFTimeInterval timeOffset;
@property float repeatCount;
@property CFTimeInterval repeatDuration;
@property BOOL autoreverses;
@property(copy) NSString *fillMode;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容