CALayer 进阶

摘要:
通过UIView的图层属性调整UIView的显示效果//content(如图片CGImageRef)@property(retain)idcontents;UIView将自动创建一个层(即CALayer对象),系统将将该层复制到屏幕上。存在隐式动画(当修改RootLayer以外的某些属性时,修改此属性将生成缩放动画。修改此属性会生成背景的渐变动画。

转载自:http://www.cofcool.net/development/2015/06/19/ios-study-note-eight-CALayer-info/

The CALayer class manages image-based content and allows you to perform animations on that content. Layers are often used to provide the backing store for views but can also be used without a view to display content. A layer’s main job is to manage the visual content that you provide but the layer itself has visual attributes that can be set, such as a background color, border, and shadow.

从上述文档中,可以看到CALayer主要负责显示内容,通过UIView的layer属性来调整UIView的显示效果,包括背景颜色、边框、阴影等和控制内容的动画效果等。CALayer是被定义在QuartzCore框架中的,因此要想使用CALayer,先导入QuartzCore框架。

常用属性:

// 宽度和高度
@property CGRect bounds;

// 位置(默认指中点,具体由anchorPoint决定)
@property CGPoint position;

// 锚点(x,y的范围都是0-1),决定了position的含义
@property CGPoint anchorPoint;

// 背景颜色(CGColorRef类型)
@property CGColorRef backgroundColor;

// 形变属性
@property CATransform3D transform;

// 边框颜色(CGColorRef类型)
@property CGColorRef borderColor;

// 边框宽度
@property CGFloat borderWidth;

// 圆角半径
@property CGColorRef borderColor;

// 内容(比如设置为图片CGImageRef)
@property(retain) id contents;

UIView之所以能显示在屏幕上,完全是因为它内部的一个图层,在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示。换句话说,UIView本身不具备显示的功能,是它内部的图层才有显示功能。通过操作CALayer对象可以方便的调整UIView的一些外观属性。需要注意的是CALayer不能处理用户的触摸事件,而UIView可以。CALayer有2个非常重要的属性:position和anchorPoint。

  • @property CGPoint position:该属性用来设置CALayer在父层中的位置,以父层的左上角为原点(0, 0)

  • @property CGPoint anchorPoint:该属性称为“定位点”、“锚点”,决定着CALayer身上的哪个点会在position属性所指的位置,以自己的左上角为原点(0, 0),它的x、y取值范围都是0~1,默认值为(0.5, 0.5)

每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)。所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画(当对非Root Layer的部分属性进行修改时,默认会自动产生一些动画效果,而这些属性称为Animatable Properties(可动画属性))。常见的Animatable Properties:

bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画。
backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画。
position:用于设置CALayer的位置。修改这个属性会产生平移动画。

可以通过动画事务(CATransaction)关闭默认的隐式动画效果。

[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];

自定义图层方法:

1. 方法1

  1. 创建一个CALayer的子类,然后覆盖drawInContext:方法,使用Quartz2D API进行绘图。
  2. 在.m文件中覆盖drawInContext:方法,在里面绘图。

     // 绘制一个实心三角形
     - (void)drawInContext:(CGContextRef)ctx {
          // 设置为蓝色
          CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
    	     
          // 设置起点
          CGContextMoveToPoint(ctx, 50, 0);
          // 从(50, 0)连线到(0, 100)
          CGContextAddLineToPoint(ctx, 0, 100);
          // 从(0, 100)连线到(100, 100)
          CGContextAddLineToPoint(ctx, 100, 100);
          // 合并路径,连接起点和终点
          CGContextClosePath(ctx);
    	     
          // 绘制路径
          CGContextFillPath(ctx);
      }
    
  3. 在控制器中添加图层到屏幕上,一定要调用setNeedsDisplay方法,这样才会触发drawInContext:方法,从而进行绘图。

     MYLayer *layer = [MYLayer layer];
     // 设置层的宽高
     layer.bounds = CGRectMake(0, 0, 100, 100);
     // 设置层的位置
     layer.position = CGPointMake(100, 100);
     // 开始绘制图层
     [layer setNeedsDisplay];
     [self.view.layer addSublayer:layer];
    

2. 方法2

设置CALayer的delegate,然后让delegate实现drawLayer:inContext:方法,当CALayer需要绘图时,会调用delegate的drawLayer:inContext:方法进行绘图。需要注意的是:不能再将某个UIView设置为CALayer的delegate,因为UIView对象已经是它内部根层的delegate,再次设置为其他层的delegate就会出问题。

  1. 在控制器中创建新的层,设置delegate,然后添加到控制器的view的layer中。

     CALayer *layer = [CALayer layer];
     // 设置delegate
     layer.delegate = self;
     // 设置层的宽高
     layer.bounds = CGRectMake(0, 0, 100, 100);
     // 设置层的位置
     layer.position = CGPointMake(100, 100);
     // 开始绘制图层
     [layer setNeedsDisplay];
     [self.view.layer addSublayer:layer];
    
  2. 让CALayer的delegate(前面设置的控制器)实现drawLayer:inContext:方法。

     // 画一个矩形框
     - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
          // 设置蓝色
          CGContextSetRGBStrokeColor(ctx, 0, 0, 1, 1);
    	     
          // 设置边框宽度
          CGContextSetLineWidth(ctx, 10);
    	     
          // 添加一个跟层一样大的矩形到路径中
          CGContextAddRect(ctx, layer.bounds);
    	     
          // 绘制路径
          CGContextStrokePath(ctx);
      } 
    

3. 总结

当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法,从而完成绘制。平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由图层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入图层的CGContextRef中,然后被拷贝至屏幕显示出来。

免责声明:文章转载自《CALayer 进阶》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SQL如何查询连续数字并且统计连续个数echarts之tooltip-trigger下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java 9 尝鲜之JShell交互式编程环境

JShell——Java 9 的交互式编程环境 本文要求读者有基本的 Java 知识。 Tips Java 9 的代码由于提供了新特性,所以有些代码并不支持向后兼容。也就是说,用 Java 9 写的代码,有可能在 Java 8 或更早版本的 JDK 上不能运行。 1. 在操作系统上安装开发所需要的软件 首先,你需要下载JDK 9 (Java Develo...

matlab中集合运算函数——解析

1. unique函数  对于unique(A,'rows')而言, 速度较慢, 例:  A = randi(10,1000,100000); %生成10以下数字的1000×100000的矩阵  第一种方式:  tic [a1 b1 c1] = unique(A,'rows'); toc        运行时间  t=2.656930s;  第二种方式:...

go-swagger的简单使用

一、下载go-swagger go-swagger 官方下载 根据不同个的操作系统选择对应的 二、添加环境变量 2.1 window swagger_windows_amd64.exe 将swagger_windows_amd64.exe 重命名 成 swagger.exe 然后将该软件放到$GOROOT/bin 中 2.2 linux swagger...

jQuery打印Html页面自动分页

最近项目中需要用到打印HTML页面,需要指定区域打印,使用jquery.PrintArea.js 插件 用法:  Javascript代码   $("div#printmain").printArea();   但还是会打印DIV后面的内容,这里可以使用CSS控制打印分页  Css代码   <div style="page-break-a...

Scalaz(4)- typeclass:标准类型-Equal,Order,Show,Enum

  Scalaz是由一堆的typeclass组成。每一个typeclass具备自己特殊的功能。用户可以通过随意多态(ad-hoc polymorphism)把这些功能施用在自己定义的类型上。scala这个编程语言借鉴了纯函数编程语言Haskell的许多概念。typeclass这个名字就是从Haskell里引用过来的。只不过在Haskell里用的名称是typ...

Scala核心编程_第06章 面向对象编程(基础部分)

面向对象的Scala Java是面向对象的编程语言,由于历史原因,Java中还存在着非面向对象的内容:基本类型 ,null,静态方法等。 Scala语言来自于Java,所以天生就是面向对象的语言,而且Scala是纯粹的面向对象的语言,即在Scala中,一切皆为对象。 如何定义类 基本语法 [修饰符] class 类名 { 类体 } 注意: scala语法中...