文档章节

iOS——CALayer(图层类)

kinglin_fu
 kinglin_fu
发布于 2016/01/15 17:27
字数 2570
阅读 281
收藏 3

###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];

© 著作权归作者所有

kinglin_fu
粉丝 16
博文 11
码字总数 14320
作品 0
石景山
私信 提问
GPU vs CPU in iOS

一直以来,我们做产品的时候并没有特别的去考虑CPU/GPU的使用,最近为了提升可视化功能的性能,发现合理使用GPU也是一个可以好好研究的部分,这里总结一下一些有用的信息。 中央处理器 CPU ...

雨_树
2018/07/10
0
0
[iOS Animation]-CALayer 专用图层 富文本

富文本 iOS 6中,Apple给UILabel和其他UIKit文本视图添加了直接的属性化字符串的支持,应该说这是一个很方便的特性。不过事实上从iOS3.2开始CATextLayer就已经支持属性化字符串了。这样的话,...

浩浩老师
2015/09/23
0
0
iOS开发系列--让你的应用“动”起来

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jianxin160/article/details/47753223 --iOS核心动画 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动...

KenshinCui
2015/08/18
0
0
CALayer与UIView的关系

UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,...

Megan_zhou
2014/04/30
0
0
iOS开发系列--让你的应用“动”起来

概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画...

creeve
2014/10/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

读书replay《maven实战》.1.20190526

前情提要 maven这个工具用了好久了,但是一直都用的迷迷糊糊的,没有对它进行过系统性的学习,只是知道一些常用的功能怎么实现,所以20190516这一天我从JD购买了徐晓斌老师所著的《maven实战...

wanxiangming
32分钟前
0
0
真实项目案例实战——【状态设计模式】使用场景

什么是状态模式 状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。 状态模式应用场景 1.一个对象的行为取决于它的状态,并且它必须在运行时刻根...

须臾之余
39分钟前
1
0
Java 实现把字符串转换成整数【底层实现】

https://blog.csdn.net/zl18310999566/article/details/80263396

qimh
42分钟前
0
0
IDEA的debugger

1、win下节省内存空间 3、条件断点

一只小青蛙
53分钟前
3
0
炸!亿级数据DB秒级平滑扩容

一步一步,娓娓道来。 一般来说,并发量大,吞吐量大的互联网分层架构是怎么样的? 数据库上层都有一个微服务,服务层记录“业务库”与“数据库实例配置”的映射关系,通过数据库连接池向数据...

编程SHA
58分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部