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"];

总结:

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

你可能感兴趣的:(iOS核心动画(CoreAnimation)最实用解析)