QuartzCore绘图以及Calayer动画

2016-01-11 | 阅读

关于绘图与动画,主要看这里

CAGradientLayer渐变颜色Calayer

Calayer的坐标系是以(0,0)到(1,1).

CAGradientLayer 渐变颜色Layer类.其有4个主要参数:

  • colors, 为NSArray,但是放的东西却是CGColorRef,放入Array中要进行(__bridge id)的转换.
  • locations , 一个NSNumber的数组,放着颜色变换的起点和终点.
  • startPoint ,endPoint 来决定变色的区域.以及规定了颜色变换的方向.如(0,0) 到 (1,0)是水平方向的颜色变化,(0,0)到(0,1)是垂直方向的颜色变换.

这里再详细说明一下渐变颜色的的区域和颜色设置,设置两个颜色A B的数组,对应两个位置 0.2,0.6,则在 0 - 0.2的区域内是正常的A颜色,0.6-1范围内是正常颜色B,只有中间部分0.2 - 0.6是颜色渐变部分.如果有三个颜色,那么左右两个边缘的颜色始终是不变色的,只有中间部分是渐变颜色区域.

示例代码:

_scanLine = [[CALayer alloc] init];
_scanLine.frame = CGRectMake(_boxViewLT.x, _boxViewLT.y ,_boxSize, 1);
CAGradientLayer *leftLayer = [[CAGradientLayer alloc] init];
leftLayer.frame = CGRectMake(0.5, 0 , _boxSize / 2 - 0.5 , 1);
leftLayer.colors = @[(__bridge id) CGColorCreateCopyWithAlpha ([UIColor grayColor].CGColor ,0.2) ,
                     (__bridge id)[UIColor greenColor].CGColor];
leftLayer.locations  = @[@(0.08), @(0.35)];
// 起始点
leftLayer.startPoint = CGPointMake(0, 0);
// 结束点
leftLayer.endPoint   = CGPointMake(1, 0);
[_scanLine addSublayer:leftLayer];

CAGradientLayer *rightLayer = [[CAGradientLayer alloc] init];
rightLayer.frame = CGRectMake(_boxSize / 2, 0 , _boxSize / 2 - 0.5 , 1);
rightLayer.colors = @[(__bridge id)[UIColor greenColor].CGColor,
                     (__bridge id) CGColorCreateCopyWithAlpha ([UIColor grayColor].CGColor ,0.2)];
rightLayer.locations  = @[@(0.65), @(0.92)];
rightLayer.startPoint = CGPointMake(0, 0);
rightLayer.endPoint   = CGPointMake(1, 0);
[_scanLine addSublayer:rightLayer];

这里是一个两边渐变颜色,中间固定颜色的扫描线,由于这个layer两边是固定颜色,只能用两个layer来组合出完整的效果.

CATransaction 动画事务

CALayer动画分为隐式动画和显式动画.

隐式动画:CAlayer中所有带有Animatable标示的属性都具有隐式动画功能,设置这些属性后,并不是在下一个RunLoop直接将属性修改,而是通过一个动画来完成这些操作.这里要求一个前提,即修改的不是UIView的root Calayer,如果是修改Root Calayer,依旧不会产生动画.

显式动画:一般通过CATransaction来执行动画.事实上,设置Animatable属性时,就是自动创建一个事务来执行动画.

如果设置一个Animatable属性,却又不希望产生动画,可以新建一个事务来关闭动画:

[ CATransaction begin ] ;   
[ CATransaction setDisableActions : YES ] ; //关闭动画 
self . subLayer . position = CGPointMake ( 100 , 100 ) ;   
[ CATransaction commit ] ;  

CATransaction 主要由以下几个函数:

+ (void)begin;// 开始一个新的事务,事务可以进行嵌套,如果进行了嵌套,里面的事务虽然提交了,但是必须要在最外层的事务提交后才会执行.
+ (void)commit; // 提交事务,在下个周期开始动画.
+ (void)flush; // 在事务嵌套中,提交隐式的动画事务,这个隐式的动画事务就会嵌套在当前事务中(如果存在),同时会推迟这个事务的提交时间,直到隐式事务完成.
+ (void)lock; // 全局的动画锁.
+ (void)unlock;

+ (void)setAnimationDuration:(CFTimeInterval)dur;// 设置动画时间,默认为0.25s
+ (void)setAnimationTimingFunction:(nullable CAMediaTimingFunction *)function;// 设置计时函数
+ (void)setDisableActions:(BOOL)flag; // 设置是否关闭动画
+ (void)setCompletionBlock:(nullable void (^)(void))block; // 设置完成动画时的回调.

CAAnimation 动画

CAAnimation动画抽象类,派生的动画类型有:

  • CATransition:页面切换动画
  • CAAnimationGroup : 多个动画同时播放
  • CABasicAnimation : 基本单个动画
  • CAKeyframeAnimation : 关键桢动画,可以定义行动路线
  • CASpringAnimation : ios9中引入,弹簧动画.

基类属性 :

// 计时程序,可以自己实现,一般取系统提供的几种
UIViewAnimationCurveEaseInOut,         // 开始和结束时放慢速度
UIViewAnimationCurveEaseIn,            // 开始时放慢速度
UIViewAnimationCurveEaseOut,           // 结束时放慢速度.
UIViewAnimationCurveLinear  			// 纯线性时间.
@property(nullable, strong) CAMediaTimingFunction *timingFunction; 
// 委托,来设置动画开始和结束时的回调.
@property(nullable, strong) id delegate;
// 动画结束时,是否自动从依赖的Calayer上移除,默认是YES.
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;

CAAnimation 实现了CAMediaTiming,其中常用的属性有以下几种:

// 开始时间
@property CFTimeInterval beginTime;
// 持续时间,默认为0 ,但是时间是默认的 0.25秒
@property CFTimeInterval duration;
// 速度, 默认为1 ,如果是2,就是基本速度的两倍.
@property float speed;
// 重复次数,默认为0次
@property float repeatCount;
// 重复时的时间,默认为0.
@property CFTimeInterval repeatDuration;
// 自动转方向
@property BOOL autoreverses;
@property(copy) NSString *fillMode;

fillMode是很重要的,对于beginTime不为0的动画,当动画添加到图层上,什么也不会发生.对于removeOnCompletion设置为No的动画,在动画结束的时候仍然保持之前的状态.这个值就是在指明动画开始之前和结束之后,被设置动画的CALayer的属性是什么样的.填充的意思是,用动画开始或结束的值来填充开始之前和结束之后的时间.有四个常量:

  • kCAFillModeForwards : 开始时,用开始时的位置填充
  • kCAFillModeBackwards : 结束时,用结束时的位置填充
  • kCAFillModeBoth : 开始结束都填充
  • kCAFillModeRemoved : 显示之前设置的值. 待测试.

CATransition

暴露出来的动画效果有 :

  • kCATransitionFade 交叉淡化过渡
  • kCATransitionMoveIn 新视图移到旧视图上面
  • kCATransitionPush 新视图把旧视图推出去
  • kCATransitionReveal 将旧视图移开,显示下面的新视图

隐藏的效果有:

  • pageCurl 向上翻一页
  • pageUnCurl 向下翻一页
  • rippleEffect 滴水效果
  • suckEffect 收缩效果,如一块布被抽走
  • cube 立方体效果
  • oglFlip 上下翻转效果

主要提供的属性有 :

@property(copy) NSString *type;// 动画类型,上面列举的几项效果
@property(nullable, copy) NSString *subtype; // 具体类型,主要是方向 :kCATransitionFromRight , kCATransitionFromLeft ,kCATransitionFromTop ,kCATransitionFromBottom
@property float startProgress; // 动画开始的进度,如 0.5,只在从50%的位置开始动画
@property float endProgress;// 动画结束时的进度.