iOS动画总结

作者: 欣东 | 来源:发表于2016-05-03 18:52 被阅读1027次

    前言

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

    iOS图形分层

    uikit.png

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

    UIKit层

    UIViewAnimation

    动画的实现过程:

    [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

    动画的实现过程:

    
    //动画持续时间、延迟时间、动画执行函数
    [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
    这个就是苹果帮开发者封装好的一些动画

    停止动画

    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    
         // 让CALayer的时间停止走动
         layer.speed = 0.0;
         // 让CALayer的时间停留在pausedTime这个时刻
         layer.timeOffset = pausedTime;
    

    恢复动画

    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附录表:

    keypath.png
    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保存这些数值

    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属性来更改动画的开始时间

    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 镜头快门开

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

    欢迎关注我的octopress 博客:http://caixindong.github.io

    相关文章

      网友评论

      • Darren_xu:有没有demo啊
        欣东:@Darren_xu 到时我整理下,发到github 上

      本文标题:iOS动画总结

      本文链接:https://www.haomeiwen.com/subject/ygcrrttx.html