zoukankan      html  css  js  c++  java
  • UI进阶--核心动画(Core Animation)

    Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍,使用它需要先添加QuartzCore.framework和引入对应的框架<QuartzCore/QuartzCore.h>。
    开发步骤:
    ①初始化一个动画对象(CAAnimation)并设置一些动画相关属性
    ②添加动画对象到层(CALayer)中,开始执行动画
    CALayer中很多属性都可以通过CAAnimation实现动画效果,包括:opacity、position、transform、bounds、contents等(可以在API文档中搜索:CALayer Animatable Properties)


    通过调用CALayer的addAnimation:forKey增加动画到层(CALayer)中,这样就能触发动画了。通过调用removeAnimationForKey可以停止层中的动画
    Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。

    CAAnimation继承结构:

    CAAnimation:

    所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
    属性解析:(红色代表来自CAMediaTiming协议的属性)
    duration:动画的持续时间
    repeatCount:动画的重复次数
    repeatDuration:动画的重复时间
    removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
    fillMode:决定当前对象在非active时间段的行为.比如动画开始之前,动画结束之后
    beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
    timingFunction:速度控制函数,控制动画运行的节奏
    • 1.kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
    • 2.kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
    • 3.kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
    • 4.kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为
    delegate:动画代理
     
    CAPropertyAnimation:
    是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:CABasicAnimation和CAKeyframeAnimation
    属性解析:
    keyPath:通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@”position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果.
      CABasicAnimation:
      CAPropertyAnimation的子类
      属性解析:
      fromValue:keyPath相应属性的初始值
      toValue:keyPath相应属性的结束值
      随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue
      如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。比如,CALayer的position初始值为(0,0),CABasicAnimation的fromValue为(10,10),toValue为(100,100),虽然动画执行完毕后图层保持在(100,100)这个位置,实质上图层的position还是为(0,0).
    示例代码:
      1 //
      2 //  ViewController.m
      3 //  CABasicAnimation
      4 //
      5 //  Created by xiaomoge on 15/1/6.
      6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
      7 //
      8 
      9 #import "ViewController.h"
     10 
     11 @interface ViewController ()
     12 @property (weak, nonatomic) IBOutlet UIView *testView;
     13 
     14 @end
     15 
     16 @implementation ViewController
     17 
     18 - (void)viewDidLoad {
     19     [super viewDidLoad];
     20     //[self testBasicTranslation];
     21 }
     22 
     23 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     24     //[self testBasicTranslation];
     25     //[self testBasicRotation];
     26     //[self testBasicScale];
     27     //[self testBasicBounds];
     28     [self testPosition];
     29 }
     30 #pragma mark - 平移动画
     31 - (void)testBasicTranslation {
     32     //创建动画对象
     33     CABasicAnimation *translationAni = [CABasicAnimation animation];
     34     //设置动画的属性
     35     
     36     //keyPath 是一个路径式, 或者说是类型
     37     translationAni.keyPath = @"transform.translation.y";
     38     //动画开始位置
     39     translationAni.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
     40     //动画结束的位置
     41     //translationAni.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 200)];;
     42     //动画位置增加的值
     43    //translationAni.byValue = @100;
     44     //动画位置增加到的值
     45     translationAni.toValue = @200;
     46     translationAni.duration = 5;
     47     //添加动画进view的layer
     48     [self.testView.layer addAnimation:translationAni forKey:nil];
     49     
     50 }
     51 #pragma mark - 旋转动画
     52 - (void)testBasicRotation {
     53     //创建一个动画对象
     54     CABasicAnimation *rotationAni = [CABasicAnimation animation];
     55     //设置动画的属性
     56     rotationAni.keyPath = @"transform.rotation";
     57     rotationAni.byValue = @(M_PI_4);
     58     rotationAni.duration = 3;
     59     //添加动画
     60     [self.testView.layer addAnimation:rotationAni forKey:nil];
     61 }
     62 #pragma mark - 缩放动画
     63 - (void)testBasicScale {
     64     //创建一个动画对象
     65     CABasicAnimation *scaleAni = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
     66     //设置动画的属性
     67     scaleAni.byValue = @1.5;
     68     scaleAni.duration = 3;
     69     //添加动画
     70     [self.testView.layer addAnimation:scaleAni forKey:nil];
     71 }
     72 #pragma mark - bounds
     73 - (void)testBasicBounds {
     74     //创建一个动画对象
     75     CABasicAnimation *boundsAni = [CABasicAnimation animationWithKeyPath:@"bounds"];
     76     //设置动画的属性
     77     boundsAni.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 300, 400)];
     78     boundsAni.duration = 3;
     79     //添加动画
     80     [self.testView.layer addAnimation:boundsAni forKey:nil];
     81 }
     82 #pragma mark - position 
     83 - (void)testPosition {
     84     //创建一个动画对象
     85     CABasicAnimation *positionAni = [CABasicAnimation animationWithKeyPath:@"position"];
     86     //设置动画的属性
     87     positionAni.byValue = [NSValue valueWithCGPoint:CGPointMake(15, 15)];
     88     positionAni.duration = 3;
     89     //如果想保持动画后的效果:方案1:代理(- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag方法)
     90     //positionAni.delegate = self;
     91     //方案2:设置动画的两个属性
     92     positionAni.removedOnCompletion = NO;//动画对象不要移除
     93     positionAni.fillMode = kCAFillModeForwards;//保存当前状态
     94     
     95     //添加动画
     96     [self.testView.layer addAnimation:positionAni forKey:nil];
     97 }
     98 #pragma mark - 动画代理方法
     99 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    100     self.testView.frame = CGRectMake(115, 115,self.testView.frame.size.width,self.testView.frame.size.height);
    101 }
    102 @end
     CAKeyframeAnimation:
     CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值
     属性解析:
     values:就是上述的NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
     path:可以设置一个CGPathRefCGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略
     keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的
     CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation。
     示例代码:
     1 //
     2 //  ViewController.m
     3 //  CAKeyframeAnimation
     4 //
     5 //  Created by xiaomoge on 15/1/6.
     6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 
    11 @interface ViewController ()
    12 @property (weak, nonatomic) IBOutlet UIView *imgView;
    13 
    14 @end
    15 
    16 @implementation ViewController
    17 
    18 - (void)viewDidLoad {
    19     [super viewDidLoad];
    20     // Do any additional setup after loading the view, typically from a nib.
    21 }
    22 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    23     //创建一个帧动画,类型为position
    24     CAKeyframeAnimation *keyframeAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    25     //设置动画的属性
    26     NSValue *val1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    27     NSValue *val2 = [NSValue valueWithCGPoint:CGPointMake(200, 200)];
    28     //values是一个数组,存储的都是一个轨迹
    29     keyframeAni.values = @[val1,val2];
    30     //动画重复次数
    31     keyframeAni.repeatCount = 3;
    32     //kCAMediaTimingFunctionEaseIn 先慢后快
    33     //kCAMediaTimingFunctionEaseOut 先快后慢
    34     //kCAMediaTimingFunctionLinear 线性匀速
    35     //kCAMediaTimingFunctionEaseInEaseOut 中间快两边慢
    36     //创建动画的节奏
    37     keyframeAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    38     //创建一个路径
    39     CGMutablePathRef path = CGPathCreateMutable();
    40     CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
    41     //绘制一个路径
    42     CGPathAddEllipseInRect(path, Nil, CGRectMake(0, 0, screenW, screenW));
    43     //设置动画的path属性
    44     keyframeAni.path = path;
    45     //c语言的create后,还要记得销毁
    46     CGPathRelease(path);
    47     //动画的时间
    48     keyframeAni.duration = 3;
    49     //添加动画进图层
    50     [self.imgView.layer addAnimation:keyframeAni forKey:nil];
    51 }
    52 @end
     
    CAAnimationGroup:
    CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行
    属性解析:
    animations:用来保存一组动画对象的NSArray
    默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间。
    示例代码:
     1 //
     2 //  ViewController.m
     3 //  CAAnimationGroup
     4 //
     5 //  Created by xiaomoge on 15/1/6.
     6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 
    11 @interface ViewController ()
    12 //storyboard上拖拉的一个UIView控件
    13 @property (weak, nonatomic) IBOutlet UIView *imgView;
    14 
    15 @end
    16 
    17 @implementation ViewController
    18 
    19 - (void)viewDidLoad {
    20     [super viewDidLoad];
    21     // Do any additional setup after loading the view, typically from a nib.
    22 }
    23 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    24     //创建一个组动画
    25     CAAnimationGroup *groupAni = [CAAnimationGroup animation];
    26     
    27     //添加平移动画
    28     CABasicAnimation *transilationAni = [CABasicAnimation animationWithKeyPath:@"position"];
    29    // transilationAni.duration = 5;
    30     transilationAni.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 400)];
    31     
    32     //添加旋转动画
    33     CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    34     rotation.toValue =@(M_PI_2);
    35     //rotation.duration = 5;
    36     
    37     //添加缩放动画
    38     CABasicAnimation *scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    39     scale.byValue = @1.2;
    40     //scale.duration = 5;注意,动画的时间由组动画来控制即可
    41 
    42     //组动画的属性设置,添加进动画组
    43     groupAni.animations = @[transilationAni,rotation,scale];
    44     groupAni.duration = 5;
    45     [self.imgView.layer addAnimation:groupAni forKey:nil];
    46 }
    47 @end
     
    CATransition:
    CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点
    UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果
    属性解析:
    type:动画过渡类型
    subtype:动画过渡方向
    startProgress:动画起点(在整体动画的百分比)
    endProgress:动画终点(在整体动画的百分比)
    动画过渡类型:
     1 fade     //交叉淡化过渡(不支持过渡方向) kCATransitionFade
     2 push     //新视图把旧视图推出去  kCATransitionPush
     3 moveIn   //新视图移到旧视图上面   kCATransitionMoveIn
     4 reveal   //将旧视图移开,显示下面的新视图  kCATransitionReveal
     5 cube     //立方体翻滚效果
     6 oglFlip  //上下左右翻转效果
     7 suckEffect   //收缩效果,如一块布被抽走(不支持过渡方向)
     8 rippleEffect //滴水效果(不支持过渡方向)
     9 pageCurl     //向上翻页效果
    10 pageUnCurl   //向下翻页效果
    11 cameraIrisHollowOpen  //相机镜头打开效果(不支持过渡方向)
    12 cameraIrisHollowClose //相机镜头关上效果(不支持过渡方向)

    示例代码:

     1 //
     2 //  ViewController.m
     3 //  CATransition
     4 //
     5 //  Created by xiaomoge on 15/1/6.
     6 //  Copyright (c) 2015年 xiaomoge. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 
    11 @interface ViewController ()
    12 //storyboard上拖拉的一个UIImageView控件,大小和屏幕一致
    13 @property (weak, nonatomic) IBOutlet UIImageView *imgView;
    14 //storyboard上拖拉的一个UITapGestureRecognizer控件
    15 - (IBAction)tapView:(UITapGestureRecognizer *)sender;
    16 //图片数组
    17 @property (nonatomic,strong) NSMutableArray *imgs;
    18 //图片的索引
    19 @property (nonatomic,assign) NSInteger imgIndex;
    20 @end
    21 
    22 @implementation ViewController
    23 #pragma mark - 懒加载图片
    24 - (NSMutableArray *)imgs {
    25     if (!_imgs) {
    26         _imgs = [NSMutableArray array];
    27         for (int i = 0; i < 9; i++) {
    28             NSString *imgName = [NSString stringWithFormat:@"%d.jpg",i + 1];
    29             [_imgs addObject:imgName];
    30         }
    31     }
    32     return _imgs;
    33 }
    34 - (void)viewDidLoad {
    35     [super viewDidLoad];
    36     // Do any additional setup after loading the view, typically from a nib.
    37 }
    38 #pragma mark - 手势识别事件
    39 - (IBAction)tapView:(UITapGestureRecognizer *)sender {
    40     
    41     CGPoint poi = [sender locationInView:sender.view];//取得手势的触摸点
    42     if (poi.x <= sender.view.bounds.size.width * 0.5) {
    43         [self previous];//如果触摸点在左边,执行上一张事件
    44     }else {
    45         [self next];//否则执行下一张事件
    46     }
    47 }
    48 #pragma mark - 上一张事件
    49 - (void)previous {
    50     if (self.imgIndex == 0) return;//如果当前是第一张,直接返回
    51     self.imgIndex --;
    52     self.imgView.image =[UIImage imageNamed: self.imgs[self.imgIndex]];//更换对应的图片
    53     [self addCaTransition];//执行动画
    54 }
    55 #pragma mark - 下一张事件
    56 - (void)next {
    57     if (self.imgIndex == self.imgs.count - 1) return;//如果是最后一张,直接返回
    58     self.imgIndex ++;
    59     self.imgView.image =[UIImage imageNamed: self.imgs[self.imgIndex]];//更换对应的图片
    60     [self addCaTransition];//执行动画
    61 }
    62 #pragma mark - 创建动画事件
    63 - (void)addCaTransition {
    64     //创建一个动画对象
    65     CATransition *transition = [CATransition animation];
    66     //设置动画的属性
    67     transition.type = @"push";//动画的类型,可选用其他
    68     transition.duration = 2;//动画的时间
    69     //添加进图层
    70     [self.imgView.layer addAnimation:transition forKey:nil];
    71 }
    72 @end
  • 相关阅读:
    POJ 1003 解题报告
    POJ 1004 解题报告
    POJ-1002 解题报告
    vi--文本编辑常用快捷键之光标移动
    常用图表工具
    September 05th 2017 Week 36th Tuesday
    September 04th 2017 Week 36th Monday
    September 03rd 2017 Week 36th Sunday
    September 02nd 2017 Week 35th Saturday
    September 01st 2017 Week 35th Friday
  • 原文地址:https://www.cnblogs.com/xiaomoge/p/4207388.html
Copyright © 2011-2022 走看看