iOS动画总结

前言

做个知识汇总,日常动画的动画实现,看这篇应该足够了

iOS图形分层

越顶层,动画的封装程度越高,动画api就越简洁,本文章主要讲动画在UIKit层和CoreAnimation层的实现

UIKit层

UIViewAnimation

动画的实现过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[UIView beginAnimations:@"newAnimation" context:nil];
//设置动画的持续时间
[UIView setAnimationDuration:1.0];
//如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
[UIView setAnimationRepeatAutoreverses:YES];
//设置动画的运动曲线(线性、先快后慢、先慢后快)
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//动画的重复次数
[UIView setAnimationRepeatCount:10];

//动画动作定义
CGRect tmp = self.myView.frame;
tmp.origin.x += 100;
self.myView.frame = tmp;

//提交动画
[UIView commitAnimations];

UIViewAnimationWithBlocks

动画的实现过程:

1
2
3
4
5
6
7
//动画持续时间、延迟时间、动画执行函数
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut  animations:^{
//动画动作定义
CGRect tmp = self.myView.frame;
tmp.origin.x = 300;
self.myView.frame = tmp;
    } completion:nil];

Core Animation

Core Animation是直接作用在CALayer上的(并非UIView上)非常强大的跨Mac OS X和iOS平台的动画处理API,Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。

CAAnimation可分为四种: 1.CABasicAnimation
通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
2.CAKeyframeAnimation
Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
3.CAAnimationGroup
Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,如何按顺序执行我到时候再讲。
4.CATransition
这个就是苹果帮开发者封装好的一些动画

停止动画

1
2
3
4
5
6
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

     // 让CALayer的时间停止走动
     layer.speed = 0.0;
     // 让CALayer的时间停留在pausedTime这个时刻
     layer.timeOffset = pausedTime;

恢复动画

1
2
3
4
5
6
7
8
9
10
11
CFTimeInterval pausedTime = layer.timeOffset;
      // 1. 让CALayer的时间继续行走
        layer.speed = 1.0;
      // 2. 取消上次记录的停留时刻
        layer.timeOffset = 0.0;
      // 3. 取消上次设置的时间
        layer.beginTime = 0.0;
      // 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime)
      CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
      // 5. 设置相对于父坐标系的开始时间(往后退timeSincePause)
        layer.beginTime = timeSincePause;

CABasicAnimation的实现

基础动画,是CAPropertyAnimation子类
keyPath附录表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CALayer* scaleLayer = [[CALayer alloc]init];
    scaleLayer.backgroundColor = [UIColor blueColor].CGColor;
    scaleLayer.frame = CGRectMake(60, 20, 50, 50);
    scaleLayer.cornerRadius = 10;
    [self.view.layer addSublayer:scaleLayer];

    //动画类型
    CABasicAnimation* scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    //动画的起始状态
    scaleAnimation.fromValue = @1.0;
    //动画的结束状态
    scaleAnimation.toValue = @1.5;
    //如果设置为YES,代表动画每次重复执行的效果会跟上一次相反
    scaleAnimation.autoreverses = YES;
    /**
    * fillMode决定当前对象在非active时间段的行为。(要想fillMode有效,最好设置removedOnCompletion = NO)
    **/
    scaleAnimation.fillMode = kCAFillModeForwards;
    //动画重复次数
    scaleAnimation.repeatCount = MAXFLOAT;
    //动画持续时间
    scaleAnimation.duration = 0.8;
      //将动画添加到layer上面
    [scaleLayer addAnimation:scaleAnimation forKey:@"scaleAnimation"];

CAKeyframeAnimation的实现

关键帧动画,也是CAPropertyAnimation的子类 与CABasicAnimation的区别是: CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CALayer* blackPoint = [[CALayer alloc]init];
    blackPoint.frame = CGRectMake(20, 80, 20, 20);
    blackPoint.backgroundColor = [UIColor blackColor].CGColor;
    blackPoint.cornerRadius = 10;
    [self.view.layer addSublayer:blackPoint];

    CGFloat originY = blackPoint.frame.origin.y;

    CAKeyframeAnimation* keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //记录每一个关键帧
    keyAnimation.values = @[[NSValue valueWithCGPoint:blackPoint.frame.origin],[NSValue valueWithCGPoint:CGPointMake(220, originY)],[NSValue valueWithCGPoint:blackPoint.frame.origin]];
    //可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的
    keyAnimation.keyTimes = @[[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.5],
                              [NSNumber numberWithFloat:1]];
   //指定时间函数
    keyAnimation.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                                                               [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
    keyAnimation.repeatCount = 1000;
    keyAnimation.autoreverses = YES;
    keyAnimation.calculationMode = kCAAnimationLinear;
    keyAnimation.duration = 4;
    [blackPoint addAnimation:keyAnimation forKey:@"rectRunAnimation"];

CAAnimationGroup的实现

组动画,是CAAnimation的子类
可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行,可以通过设置动画对象的beginTime属性来更改动画的开始时间

1
2
3
4
5
6
7
CAAnimationGroup* group = [CAAnimationGroup animation];
  //用来保存一组动画对象
    group.animations = @[scaleAnimation];
    group.duration = 0.8;
    group.repeatCount = 3;
    group.autoreverses = YES;
    [scaleLayer addAnimation:group forKey:nil];

CATransition的实现

转场动画,是CAAnimation的子类,,能够为层提供移出屏幕和移入屏幕的动画效果。 UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果 有以下效果可以使用:
cube 方块
suckEffect 三角
rippleEffect 水波抖动
pageCurl 上翻页
pageUnCurl 下翻页
oglFlip 上下翻转
cameraIrisHollowOpen 镜头快门开
cameraIrisHollowClose 镜头快门开

1
2
3
4
5
6
7
8
9
10
11
12
13
CATransition* animation = [CATransition animation];
    animation.duration = 1.0f;
    animation.timingFunction = UIViewAnimationCurveEaseInOut;
    //执行完是否移除
    animation.removedOnCompletion = NO;
    //过渡效果
    animation.type = @"cube";
    //过渡方向
    animation.subtype = kCATransitionFromRight;
    //设置之后endProgress才有效
    animation.fillMode = kCAFillModeForwards;
    animation.endProgress = 1;
    [imageView.layer addAnimation:animation forKey:nil];

Comments