iOS核心动画(一)CAAnimation

来源:互联网 发布:华为云计算开发面试 编辑:程序博客网 时间:2024/05/06 06:30

Core Animation

简单介绍

 1. Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。 2. Core Animation是跨平台的,可以用在Mac OS X和iOS平台。 3. Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。不阻塞主线程,可以理解为在执行动画的时候还能点击(按钮)。  要注意的是,Core Animation是直接作用在CALayer上的,并非UIView。

CAAnimation

  • CAAnimation 所有动画的父类,基类(不能直接使用)。
  • CAPropertyAnimation 属性动画,通过属性值的改变 产生动画效果,基类(不能直接使用)。
  • CABasicAnimation 基础动画 -> 只能是两个点之间的变化。
  • CASpringAnimation 弹簧动画。
  • CAKeyframeAnimation 关键帧动画 -> 可以添加多个点的变化 或者 添加路径。
  • CAAnimationGroup 动画组,可以同时添加多种动画,达到预期效果。
  • CATransition 转场动画 -> 给视图切换的时候 添加动画效果。
  • CALayer 图层(动画都是基于图层)只能显示内容,不能跟用户响应,发生改变,自图层不会发生改变,当改变属性值的时候,他本身自带动画效果,这种动画效果较做隐式动画。

CALayer常用属性

  • bounds:边境范围
    • position:中心点
    • zPosition:z轴中心点
  • anchorPoint:锚点 ✮✮✮✮✮
    • anchorPointZ:Z轴锚点
      默认锚点是与中心点重合锚点最小值是0,0 最大值是1,1;默认值:0.5,0.5;当视图改变的时候,是以锚点为基准去改变。
      锚点的值与位置:
      0,0 = 在图层的左上角
      0,1 左下角
      1,0 右上角
      1,1 右下角
      锚点值 = 锚点在视图上的位置.x.y/视图的宽高
  • transform 转换形态
  • frame NO. Animatable 坐标
  • hidden 隐藏
  • doubleSided 图层背面是否显示
  • geometryFlipped 翻转 颠倒
  • masksToBounds 裁切边境
  • contents 内容
  • opaque 不透明度
  • opacity 不透明度
  • allowsEdgeAntialiasing 是否使用 变形后的抗锯齿
  • backgroundColor 背景颜色
  • borderWidth 边框宽
  • borderColor 边框颜色
  • shadowColor 阴影颜色
  • shadowOpacity 阴影不透明度
  • rasterizationScale 防止Retina屏幕像素化
  • shadowOffset 阴影偏移量

- shadowRadius 阴影的半径

CALayer与UIView的关系

   在iOS当中,所有的视图都从一个叫做UIVIew的基类派生而来,UIView可以处理触摸事件,可以支持基于Core Graphics绘图,可以做仿射变换(例如旋转或者缩放),或者简单的类似于滑动或者渐变的动画   CALayer类在概念上和UIView类似,同样也是一些被层级关系树管理的矩形块,同样也可以包含一些内容(像图片,文本或者背景色),管理子图层的位置。它们有一些方法和属性用来做动画和变换。和UIView最大的不同是CALayer不处理用户的交互。CALayer并不清楚具体的响应链(iOS通过视图层级关系用来传送触摸事件的机制),于是它并不能够响应事件,即使它提供了一些方法来判断是否一个触点在图层的范围之内。   也就是说,UIView视图,可以跟用户交互->rootLayer没有动画效果   CALayer 不可以跟用户交互 只能显示内容   UIView ->rootLayer发生改变,子图层也会发生改变   CALayer发生改变,子图层不会跟随发生改变

UIView与CALayer同级存在的意义

   是要做职责分离,这样也能避免很多重复代码。在iOS和Mac OS两个平台上,事件和用户交互有很多地方的不同,基于多点触控的用户界面和基于鼠标键盘有着本质的区别,这就是为什么iOS有UIKit和UIView,但是Mac OS有AppKit和NSView的原因。他们功能上很相似,但是在实现上有着显著的区别。   绘图,布局和动画,相比之下就是类似Mac笔记本和桌面系列一样应用于iPhone和iPad触屏的概念。把这种功能的逻辑分开并应用到独立的Core Animation框架,苹果就能够在iOS和Mac OS之间共享代码,使得对苹果自己的OS开发团队和第三方开发者去开发两个平台的应用更加便捷。

CAAnimation子类

  • CAPropertyAnimation:属性动画。也是基类,不可以直接使用,通过属性值的改变产生动画效果。
  • CABaseAnimation:基础动画。只能两个点之间的变化(平移视图)。
  • CAKeyframeAnimation:关键帧动画。可以添加多个点的变化或路径。
  • CAAnimationGRoup:动画组。可以添加多种动画达到预期的效果。
  • CATransition:转场动画。给视图切换的时候添加动画效果

基础动画

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)

关键帧动画

CAKeyframeAnimation

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

属性

  • values:NSArray对象。里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧。

  • path:可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略 。

  • keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的 .

  • CABasicAnimation可看做是最多只有两个关键帧的CAKeyframeAnimation

    在关键帧动画中还有一个非常重要的参数,那便是calculationMode:计算模式。其主要针对的是每一帧的内容为一个座标点的情况,也就是对anchorPoint 和 position 进行的动画。当在平面座标系中有多个离散的点的时候,可以是离散的,也可以直线相连后进行插值计算,也可以使用圆滑的曲线将他们相连后进行插值计算。 

calculationMode目前提供如下几种模式:

  • kCAAnimationLinear calculationMode的默认值,表示当关键帧为座标点的时候,关键帧之间直接直线相连进行插值计算;

  • 
kCAAnimationDiscrete 离散的,就是不进行插值计算,所有关键帧直接逐个进行显示;

  • 
kCAAnimationPaced 使得动画均匀进行,而不是按keyTimes设置的或者按关键帧平分时间,此时keyTimes和timingFunctions无效;

    • kCAAnimationCubic 对关键帧为座标点的关键帧进行圆滑曲线相连后插值计算,这里的主要目的是使得运行的轨迹变得圆滑;
  • kCAAnimationCubicPaced 看这个名字就知道和kCAAnimationCubic有一定联系,其实就是在kCAAnimationCubic的基础上使得动画运行变得均匀,就是系统时间内运动的距离相同,此时keyTimes以及timingFunctions也是无效的。

动画组

CAAnimationGroup

  CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行.

属性

  • animations:用来保存一组动画对象的NSArray。默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的beginTime属性来更改动画的开始时间.

转场动画

CATransition

  • CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点。

  • UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果.

属性:

  • type:动画过渡类型

  • subtype:动画过渡方向

  • startProgress:动画起点(在整体动画的百分比)

  • endProgress:动画终点(在整体动画的百分比)

#import "ViewController.h"#define Angle(a) (a)*M_PI/180#define sAngle 6    //每秒旋转多少度:sAngle*N秒*M_PI/180@interface ViewController (){    CALayer *layer;}@property (nonatomic,strong)CALayer *pointLayer;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];//   初始化CAlayer    layer = [CALayer layer];    layer.frame = CGRectMake(100, 100, 100, 100);//   设置图层拐角    layer.cornerRadius = 100/2;    layer.backgroundColor =[UIColor brownColor].CGColor;//   添加到父图层    [self.view.layer addSublayer:layer];//    NSLog(@"%@",self.pointLayer);    _pointLayer.anchorPoint =CGPointMake(0, 0.5);//   放置一张图片//   图层上 要的是颜色(CGColorRef)  图片(CGImageRef)的 数据,而非UI    _pointLayer.contents =(id)[UIImage imageNamed:@"shizhen.png"].CGImage;    self.pointLayer.anchorPoint = CGPointMake(0.5, 0.9);    [self star];    [NSTimer scheduledTimerWithTimeInterval:1                                     target:self selector:@selector(star) userInfo:nil repeats:YES];}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//   获得点击触摸的点    layer.position =[[touches anyObject] locationInView:self.view];    CGFloat width =CGRectGetWidth(layer.bounds)!=100?100:50;//   通过获得的点 改变尺寸    layer.bounds =CGRectMake(0, 0, width, width);//   改变颜色    CGColorRef color = [UIColor brownColor].CGColor != layer.backgroundColor ?    [UIColor brownColor].CGColor:    [UIColor colorWithRed:0.863                    green:0.634                     blue:0.490                    alpha:1.000].CGColor;    layer.backgroundColor = color;//   改变半径    layer.cornerRadius =width!=100?0:width/2;//   改变透明度    layer.opacity = 0.3;//   设置锚点,最大值是1,最小值是0 //   _pointLayer.transform = CATransform3DMakeRotation(/*弧度*/Angle(60),0 , 0, 1);}-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    layer.opacity = 1.0;//   还原  //  _pointLayer.transform = CATransform3DIdentity;}//利用懒加载 创建一个layer-(CALayer *)pointLayer{    if (_pointLayer) {        return _pointLayer;    }    _pointLayer = [CALayer layer];    _pointLayer.bounds =CGRectMake(0, 0, 18, 220);    //设置中心点    _pointLayer.position =self.view.center;    _pointLayer.backgroundColor =    [UIColor colorWithRed:1.000                    green:0.392                     blue:0.929                    alpha:1.000].CGColor;    [self.view.layer addSublayer:_pointLayer];    return _pointLayer;}-(void)star{//   NSCalendar 日历;可以获得年月日 时分秒,都是NSCalendar上的组件//    NSDateComponents//   获得当前日历    NSCalendar *calender =[NSCalendar currentCalendar];    NSDateComponents *componest =[calender components:                                  NSCalendarUnitHour|                                  NSCalendarUnitMinute|                                  NSCalendarUnitSecond fromDate:[NSDate date]];    float s = componest.second * sAngle;    _pointLayer.transform = CATransform3DMakeRotation(/*弧度*/Angle(s),0 , 0, 1);}@end
0 0