###1、CALayer(图层类)的基本概括

  • CALayer 是整个图层类的基础,它是所有核心动画图层类的父类。
  • 和视图类(UIView)一样,CALayer 有自己的父图层类,同时也拥有自己子图层类的集合,它们构成了一个图层树的层次结构。
  • CALayer 从 Application Kit 和 Cocoa Touch 的视图类分离出来。
  • CALayer 类的内容显示可以通过以下方法提供:

1. 可以直接或者委托的方式把图层的内容属性设置为 Core Graphics image。
2. 提供直接绘制到一个 Core Graphics image 上下文委托。
3. 设置所有图层所具有的可视化样式属性,比如背景颜色、不透明属性、蒙版、边框、圆角等。
4. CAScrollLayer 是 CALayer 的子类,简化显示图层的一部分内容。CAScrollLayer 对象的滚动区域的范围在它的子图层里面定义。CAScrollLaye 不提供键盘或鼠标事件处理,也不提供可见的滚动条。
5. CATextLayer 可以方便的从字符串或字符串的内容创建一个图层类的内容。
6. CATiledLayer 允许递增的显示大而复杂的图片。
7. CAEAGLLayer 提供了一个OpenGLES渲染环境。

  • CALayer 的还扩展了 NSKeyValueCoding 的非正式协议,加入默认键值和额外的结构类型的自动对象包装 (CGPoint,CGSize,CGRect,CGAffineTransform 和 CATransform3D)的支持,并 提供许多这些结构的关键路径领域的访问。
  • CALayer 同时管理与层关联的动画和行为。图层接受层树的插入和删除层动作, 修改层的属性,或者明确的开发请求。这些行为通常会导致动画发生(隐式动画)
  • 虽然核心动画的图层和 Cocoa 的视图在很大程度上没有一定的相似性,但是他们两者**最大的区别是,图层不会直接渲染到屏幕上。**
  • 在模型-视图-控制器(model-view-controller)概念里面 NSView 和 UIView 是典 型的视图部分,但是在核心动画里面图层是模型部分。图层封装了几何、时间、可视 化属性,同时它提供了图层现实的内容,但是实际显示的过程则不是由它来完成。
  • 每个可见的图层树由两个相应的树组成:一个是呈现树,一个是渲染树。
  1. 呈现树:呈现树包含了当前动画发生时候将要显示的值,例如你要给图层背景颜色设置新 的值的时候,它会立即修改图层树里面相应的值。但是在呈现树里面背景颜色值在将 要显示给用户的时候才被更新为新值。
  2. 渲染数:渲染树在渲染图层的时候使用呈现树的值。渲染树负责执行独立于应用活动的复 杂操作。渲染由一个单独的进程或线程来执行,使其对应用程序的运行循环影响最小。

###2、图层树

  • 图层树是核心动画里面类似 Cocoa 视图的层次结构,一个核心动画的图层拥有父图层(suplayer)和子图层(sublayer)。
  • 核心动画不提供在一个窗口(window)实际显示图层的手段,它们必须通过视图来托管。当视图和图层一起的时候,视图为图层提供了底层的事件处理,而图层为视图提供了显示的内容
  • iOS 上面的视图系统直接建立在核心动画的图层上面。每个 UIView 的实例会自动的创建一个 CALayer 类的实例,然后把该实例赋值给视图的 layer 属性。
/*1、每一个UIView都会有一个layer。
      2、将layer添加到父layer中,self.view.layer为父图层,layer为子图层。
    */
    CALayer *layer = [CALayer layer];
    layer.frame = CGRectMake(100, 100, 200, 200);
    layer.backgroundColor = [UIColor blueColor].CGColor;
    [self.view.layer addSublayer:layer];

###3、给CALayer提供内容 你可以通过以下任何一种方法指定 CALayer 实例的内容:

  1. 使用包含图片内容的 CGImageRef 来显式的设置图层的 contents 的属性。
  2. 使用CALayer的子类填充内容。
  3. 指定一个委托,它提供或者重绘内容。
  4. 继承 CALayer 类重载显示的函数。
  • 设置contents属性
// 给layer添加图片内容
    CALayer *imageLayer = [CALayer layer];
    imageLayer.frame = CGRectMake(50, 100, 200, 200);
    imageLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
    UIImage *image = [UIImage imageNamed:@"心.png"];
    imageLayer.contents = (__bridge id)(image.CGImage);
    [self.view.layer addSublayer:imageLayer];
  • 使用CALayer的子类填充内容
// 填充文字的layer:CATextLayer
    CATextLayer *textLayer = [CATextLayer layer];
    textLayer.frame = CGRectMake(50, 400, 200, 30);
    textLayer.foregroundColor = [UIColor redColor].CGColor;
    textLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
    textLayer.string = @"这是填充文字的leyer";
    textLayer.fontSize = 20;
    textLayer.font = (__bridge CFTypeRef )(@"楷体");
    textLayer.alignmentMode = kCAAlignmentCenter;
    [self.view.layer addSublayer:textLayer];
  • 通过创建一个委托类实现下列方法之一:displayLayer:drawLayer:inContext:。通过发送以下任何一个方法 setNeedsDisplay 或 者 setNeedsDisplayInRect: 的消息, 或者把图层的 needsDisplayOnBoundsChange 属性值设置为 YES。
- (void)viewDidLoad {
    	[super viewDidLoad];
    	CALayer *drawLayer = [CALayer layer];
    	drawLayer.frame = CGRectMake(50, 400, 200, 200);
    	[self.view.layer addSublayer:drawLayer];
    	drawLayer.delegate = self;
    	[drawLayer setNeedsDisplay]; // 重绘
    
    }
    // CALayer的代理方法<CALayerDelegate>
    - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
   	// 画矩形
    	CGRect rect = CGRectMake(50, 0, 100, 50);
    	CGContextSetRGBFillColor(ctx, 0.1, 0.5, 0.5, 1);
    	CGContextSetRGBStrokeColor(ctx, 1.0, 0.1, 0.1, 1);
    	CGContextAddRect(ctx, rect);
    	CGContextDrawPath(ctx, kCGPathFillStroke);
	}
  • 通过子类提供图层的内容,你的图层需要定制行为而委托又无法满足需求的时候。子类可以重载 CALayer 的显示方法,设置图层的内容为适当的图片。

###4、修改图层内容的位置 CALayer 的属性 contentsGravity 允许你在图层的边界内容修改图层的 contents 图片的位置或者伸缩值。默认情况下,内容的图像完全填充层的边界,忽视自然的图像宽高比。

相应填充的位置:

1. kCAGravityTopLeft  			// 左上
	2. kCAGravityTop      			// 顶部
	3. kCAGravityTopRight 			// 右上
	4. kCAGravityLeft     			// 左
	5. kCAGravityCenter  			// 中心
	6. kCAGravityRight    			// 右
	7. kCAGravityBottomLeft 		// 左下
	8. kCAGravityBottom   			// 下
	9. kCAGravityBottomRight      // 右下
	10.kCAGravityResize           // 拉伸
	11.kCAGravityResizeAspect     // 等比例
	12.kCAGravityResizeAspectFill // 完全填充

ios 试图层级调整_图层

###5、图层样式属性

  • 几何属性:
  1. frame
  2. bounds
  3. position
  4. anchorPoint
  5. cornerRadius
  6. transform
  7. zPosition
  • 背景属性:
  1. backgroundColor
  2. backgroundFilters --滤镜(iOS不可用)
  • 图层内容:
  1. contents
  • 子图层内容:
  1. sublayers
  2. masksToBounds
  3. sublayerTransform
  • 边框属性:
  1. borderColor
  2. borderWidth
  • 滤镜属性:
  1. filters(iOS不可用)
  • 阴影属性:
  1. shadowColor
  2. shadowOffset
  3. shadowOpacity
  4. shadowRadius
  • 不透明属性:
  1. opacity
  • 混合属性:
  1. compositingFilter -- 混合滤镜(iOS不可用)
  • 遮罩属性:
  1. mask
CALayer *pLayer = [CALayer layer];
    [self.view.layer addSublayer:pLayer];
    //坐标尺寸、背景颜色
    pLayer.frame = CGRectMake(50, 100, 200, 200);
    pLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
    //内容
    pLayer.contents = (__bridge id)[UIImage imageNamed:@"image.jpg"].CGImage;
    pLayer.contentsGravity = kCAGravityResize;
    // 圆角
    pLayer.cornerRadius = 20;
    pLayer.masksToBounds = YES; // 必须设为YES圆角才起作用
    // 边框
    pLayer.borderColor = [UIColor blackColor].CGColor;
    pLayer.borderWidth = 5;
    // 阴影
    pLayer.shadowColor = [UIColor grayColor].CGColor;
    pLayer.shadowOffset = CGSizeMake(5, 5);
    pLayer.shadowOpacity = 1;
    pLayer.shadowRadius = 10;
    //透明度
    pLayer.opacity = 0.5;
    
    //坐标变换transform,缩放、旋转、移动
    pLayer.transform = CATransform3DMakeScale(0.5, 0.5, 1);
    pLayer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
    pLayer.transform = CATransform3DMakeTranslation(0, 50, 0);
    
    //KVC设置transform
    [pLayer setValue:@0.5 forKeyPath:@"transform.scale"];
    [pLayer setValue:@1.0 forKeyPath:@"transform.scale.x"];
    [pLayer setValue:@M_PI_4 forKeyPath:@"transform.rotation"];
    [pLayer setValue:@50 forKeyPath:@"transform.translation.y"];

###6、图层的行为(隐式动画)

  • 图层的行为在以下情况发生的时候被触发:从图层树里面插入或者删除一个图层,图层的属性值被修改了,或者程序显式要求。通常情况下,行为触发器是动画显示的结果所在。
  • 一个行为对象是一个通过 CAAction 协议响应行为标识符的对象。行为标识符使 用标准圆点分隔的关键路径来命名。图层负责把行为标识符映射到特定的行为对象。 当一个特定标识符的行为对象被确定的时候,它会发送一个 CAAction 协议定义的消息。
  • CALayer类提供了默认的CAAnimation的行为对象实例,一个兼容类所有动画层属性CAAction协议。
  • CALayer类提供了默认的CAAnimation的行为对象实例,一个兼容类所有动画层属性CAAction协议。
// 当改变layer属性值得时候,会自动产生一个动画,这个动画叫隐式动画
	pLayer.opacity=0.0;	
	pLayer.position=CGPointMake(0.0,0.0);
	pLayer.transform = CATransform3DMakeScale(0.5, 0.5, 1);

###7、事务 图层的每个改变都是事务的一部分。CATransaction 是核心动画类,它负责成批的把多个图层树的修改作为一个原子更新到渲染树。

  • 隐式事务:
  1. 当图层树被没有获得事务的线程修改的时候将会自动创建隐式事务,当线程的运行循环(run-loop)执行下次迭代的时候将会自动提交事务。
  2. 重要:当在一个没有运行循环(runloop)的线程修改图层的属性的时候,你必须使用显式的事务。
  • 显示事务:
  1. 在你修改图层树之前,可以通过给 CATransaction 类发送一个 begin 消息来创建一 个显式事务,修改完成之后发送 comit 消息。
  2. 你可以在修改图层属性值的时候通过设置事务的 kCATransactionDisableActions或者setDisableActions 值为 YES 来暂时禁用图层的行为。在事务范围所作的任何更改也不会因此而发生的动画。
[CATransaction begin];
	[CATransaction setValue:(id)kCFBooleanTrue
	forKey:kCATransactionDisableActions];
	//[CATransaction setDisableActions:YES];
	[aLayer removeFromSuperlayer];

 [CATransaction commit]; ```

3. 可以暂时改变响应改变图层属性的动画的时间,通过设置事务的 `kCATransactionAnimationDuration`或者`setAnimationDuration` 键的值为新的时间。

```
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
forKey:kCATransactionAnimationDuration];
//[CATransaction setAnimationDuration:10.0f];
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
[CATransaction commit];
```
  • 事务嵌套:
    显式事务可以被嵌套,允许你禁用部分动画的行为或者在属性被修改的时候产生 的动画使用不同的时间。仅当最外层的事务被提交的时候,动画才会发生。
[CATransaction begin];
    [CATransaction setAnimationDuration:2];
    pLayer.opacity = 0.0;
    
    [CATransaction begin];
    pLayer.transform = CATransform3DMakeScale(3, 3, 1);
    
    [CATransaction commit];
    [CATransaction commit];