iOS核心动画(CoreAnimation)最实用解析

CoreAnimation是iOS中的核心动画框架,是iOS开发中专门用来处理动画的API,在开发中使用CoreAnimation可以做出很多很炫酷的动画。下面,就对CoreAnimation的使用做出详细的解析。

UIView动画

在说CoreAnimation之前,可以先简单的介绍一下UIView动画,UIView动画用起来很简单,实现的动画也是非常简单。
在开发中,我们也会经常调用到,主要有两种调用方式:

  • block代码块调用

[UIView animateWithDuration:1 animations:^{
        self.firstView.frame = CGRectMake(200, 200, 50, 100);
 }];

常用的还有delay参数和completion的回调方法,completion中是动画完成后的回调,可以在做一些动画完成后要执行的任务,delay是动画延迟执行的时间。

  • [begin commit]代码段调用

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1];
self.firstView.frame = CGRectMake(200, 200, 50, 100);
[UIView commitAnimations];

这种方式需要将执行的动画内容放到beginAnimations和commitAnimations中间,包括一些要设置的属性,如:Duration、Delay、StartDate、Curve、RepeatCount等等,还可以通过设置setAnimationDelegate代理,来监听动画的开始和结束。

核心动画(CoreAnimation)

CoreAnimation的动画实现是在layer层,每一个UIView的对象在创建的时候都会生成一个layer层,我们平时看到的view上展示的元素都是layer层绘制和显示的,通过改变layer的属性,就可以实现复杂的动画了。其实,UIView动画也可以看做是CoreAnimation的封装,不过,值得注意的是:UIView动画在执行完成后,view本身是发生改变的,CoreAnimation在执行完成后,view本身是没有发生改变的,只是看起来变了而已。
CoreAnimation的基类为CAAnimation,实现了CAMediaTiming协议,以用来控制动画的时间、速度和时间曲线等,CoreAnimation不能直接使用,需要使用它的子类:CAAnimationGroup、CAPropertyAnimation和CATransition,CAPropertyAnimation一般也不会直接时候,它又有两个子类:CABasicAnimation、CAKeyframeAnimation。
综上所述,可以使用的动画的类包括:

CABasicAnimation: 基础动画
CAKeyframeAnimation: 关键帧动画
CATransition: 转场动画
CAAnimationGroup: 动画组

CABasicAnimation(基础动画)

CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
basicAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(150, 125)];
basicAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 500)];
basicAnimation.duration = 1.0f;
[self.firstView.layer addAnimation:basicAnimation forKey:@"positonAnimation"];

其中,keyPath对应的是想要改变的layer的属性,支持动画的属性主要包括以下这些:

//CATransform3D Key Paths :
rotation.x
rotation.y
rotation.z
rotation 旋轉
scale.x
scale.y
scale.z
scale 缩放
translation.x
translation.y
translation.z
translation 平移

>CGPoint Key Paths : 
   x
   y

> //CGRect Key Paths : 
 origin.x
 origin.y
 origin
 size.width
 size.height
 size

 >opacity
 backgroundColor
 cornerRadius 
 borderWidth
 contents 

 >//Shadow Key Path:
 shadowColor 
 shadowOffset 
 shadowOpacity 
 shadowRadius

经常用到的还有以下属性:

  • fillMode、removedOnCompletion,他们两个同时使用,

basicAnimation.fillMode = kCAFillModeForwards;
basicAnimation.removedOnCompletion = NO;

动画执行完成后,视图不会再回到原来的位置。

  • timingFunction :动画执行时的效果:

basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

同时,要想移除动画,系统提供了两个方法:

 - (void)removeAnimationForKey:(NSString *)key;//移除指定的动画
 - (void)removeAllAnimations;//移除某个layer上所有的动画

CAKeyframeAnimation(关键帧动画)

关键帧动画可以为动画的执行过程设置若干个中间点,中间点前后动画的属性可以设置多个不同的值,动画可以沿着设置的中间点顺序执行。

    CAKeyframeAnimation * keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    keyFrameAnimation.duration = 3.0;
    keyFrameAnimation.removedOnCompletion = NO;
    keyFrameAnimation.fillMode = kCAFillModeForwards;
    keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    NSValue * value0 = [NSValue valueWithCGPoint:CGPointMake(150, 125)];
    NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(250, 125)];
    NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(250, 225)];
    NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(100, 400)];
    keyFrameAnimation.values = @[value0, value1, value2, value3];
    [self.firstView.layer addAnimation:keyFrameAnimation forKey:@"KeyframeAnimationForPosition"];

关键帧动画有几个非常重要的属性:

values:关键帧数组对象,里面每一个元素即为一个关键帧,动画会在对应的时间段内,依次执行数组中每一个关键帧的动画。
path:动画路径对象,可以指定一个路径,在执行动画时路径会沿着路径移动,Path在动画中只会影响视图的Position。
keyTimes:设置关键帧对应的时间点,范围:0-1。如果没有设置该属性,则每一帧的时间平分。

利用path属性,我们可以使用关键帧动画来实现画圆圈的动画:

    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    keyFrameAnimation.removedOnCompletion = NO;
    keyFrameAnimation.fillMode = kCAFillModeForwards;
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(screenSize.width/2-100, screenSize.height/2-100, 200, 200)];
    keyFrameAnimation.path = path.CGPath;
    keyFrameAnimation.duration = 2.0f;
    [self.firstView.layer addAnimation:keyFrameAnimation forKey:@"KeyframeAnimationCirclePath"];

CATransition(转场动画)

    CATransition * transAnimation = [CATransition animation];
    transAnimation.type = kCATransitionFade;
    transAnimation.subtype = kCATransitionFromLeft;
    transAnimation.duration = 1.5;
    self.firstView.backgroundColor = [UIColor blueColor];
    [self.firstView.layer addAnimation:transAnimation forKey:@"transitionAnimation"];

转场动画两个重要的属性:

type:转场动画的种类,公有api主要有四个:kCATransitionFade 渐变、 kCATransitionMoveIn 覆盖、kCATransitionPush 推出、 kCATransitionReveal 揭开,还有一些私有api:"cube"、"suckEffect"、"oglFlip"、 "rippleEffect"、"pageCurl"、"pageUnCurl"
suntype:动画的方向,有以下几种:kCATransitionFromRight 从右边、kCATransitionFromLeft 从左边、 kCATransitionFromTop 从顶部、kCATransitionFromBottom 从底部

CAAnimationGroup(动画组)

CAAnimationGroup顾名思义就是一组动画,动画组中可以添加多个动画,动画组中的动画可以并发运行。我们平时见到的一些炫酷的动画,都是依赖动画组完成的。
CAAnimationGroup最重要的属性:

animations: 数组类型,用来接收动画组中要添加的动画

    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    //关键帧动画(移动)
    CAKeyframeAnimation *animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, screenSize.height/2-50)];
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(screenSize.width/3, screenSize.height/2-50)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(screenSize.width/3, screenSize.height/2+50)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(screenSize.width*2/3, screenSize.height/2-50)];
    animation1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,nil];
    //缩放动画
    CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    animation2.fromValue = [NSNumber numberWithFloat:0.8f];
    animation2.toValue = [NSNumber numberWithFloat:2.0f];
    //旋转动画
    CABasicAnimation *animation3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    animation3.toValue = [NSNumber numberWithFloat:M_PI*4];
    //组动画
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    groupAnimation.animations = [NSArray arrayWithObjects:animation1,animation2,animation3, nil];
    groupAnimation.duration = 3.0f;
    [self.firstView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];

总结:

平时大家看到的动画,无论多么复杂,都是由一个个简单的动画组合而成的,在使用的时候,我们要进行合适的组合,控制好动画的属性,就能达到我们满意的效果。

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

推荐阅读更多精彩内容