iOS——CALayer(图层类)

###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 // 完全填充

输入图片说明 ###5、图层样式属性

  • 几何属性:
    1. frame --坐标尺寸
    2. bounds --尺寸
    3. position --定位点,子图层的锚点在父图层中的哪个坐标点。
    4. anchorPoint --锚点(0 ~ 1),决定子图层哪个点在position点上、旋转的支点。默认(0.5,0.5)
    5. cornerRadius --圆角弧度
    6. transform --坐标变换,控制缩放、旋转、移动。
    7. zPosition --在父图层中的层次。
  • 背景属性:
    1. backgroundColor --背景颜色
    2. backgroundFilters --滤镜(iOS不可用)
  • 图层内容:
    1. contents
  • 子图层内容:
    1. sublayers --设置子多个图层
    2. masksToBounds --是否剪切超出父图层边界的部分,默认为NO
    3. sublayerTransform --子图层的坐标系统
  • 边框属性:
    1. borderColor -- 边框的颜色
    2. borderWidth -- 边框的宽度
  • 滤镜属性:
    1. filters(iOS不可用)
  • 阴影属性:
    1. shadowColor --阴影颜色
    2. shadowOffset --阴影尺寸,maskToBounds不能设为YES。
    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];

转载于:https://my.oschina.net/u/1993356/blog/603365

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值