美文网首页
CALayer详细讲解

CALayer详细讲解

作者: 白水灬煮一切 | 来源:发表于2017-08-23 15:16 被阅读334次

    CALayer1-简介

    本文目录

    一、什么是CALayer

    二、CALayer的简单使用

    回到顶部

    一、什么是CALayer

    * 在iOS系统中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。

    * 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个层。

    * 在创建UIView对象时,UIView内部会自动创建一个层(即CALayer对象),通过UIView的layer属性可以访问这个层。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的层上,绘图完毕后,系统会将层拷贝到屏幕上,于是就完成了UIView的显示。

    * 换句话说,UIView本身不具备显示的功能,是它内部的层才有显示功能。

    回到顶部

    二、CALayer的简单使用

    上面已经说过了,UIView之所以能够显示,完全是因为内部的CALayer对象。因此,通过操作这个CALayer对象,可以很方便地调整UIView的一些界面属性,比如:阴影、圆角大小、边框宽度和颜色等。

    1.CALayer是被定义在QuartzCore框架中的,因此要想使用CALayer,先导入QuartzCore框架

    1> 点击项目名称,然后点击右边TARGETS下面的target

    2> 点击Build Pases后,展开Link Binary....,添加 + 号

    3> 在搜索框中输入"Quartz",选中QuartzCore.framework,最后add添加

    4> 添加完毕后,这个框架就会出现在项目文件夹中

    如果你觉得位置不好看,还可以将它拖到Frameworks文件夹下,跟其他框架放一起

    2.在项目代码中导入QuartzCore框架的主头文件

    #import

    3.通过CALayer修改UIImageView的界面属性

    你也可以使用UIButton或者UILabel,这里就以UIImageView为例子

    1> 先创建一个UIImageView,添加到控制器的view中

    1UIImage *image = [UIImage imageNamed:@"lufy.png"];2UIImageView *imageView =[[[UIImageView alloc] initWithImage:image] autorelease];3imageView.center = CGPointMake(100,100);4[self.view addSubview:imageView];

    2> 设置阴影

    1imageView.layer.shadowColor=[UIColor grayColor].CGColor;2imageView.layer.shadowOffset= CGSizeMake(10,10);3imageView.layer.shadowOpacity=0.5;

    * 第1行设置阴影的颜色为灰色,注意,这里使用的是UIColor的CGColor属性,是一种CGColorRef类型的数据

    * 第2行设置阴影的偏移大小,可以看出阴影往原图的右下角偏移

    * 第3行设置阴影的不透明度为0.5,表示半透明。如果为1,代表完全不透明。

    3>设置圆角大小

    通过layer属性可以访问视图内部的CALayer对象

    1imageView.layer.cornerRadius=10;2imageView.layer.masksToBounds= YES;

    * 第1行设置圆角半径为10

    * 第2行的maskToBounds=YES:可以看做是强制内部的所有子层支持圆角效果,少了这个设置,UIImageView是不会有圆角效果的

    * 注意,如果设置了maskToBounds=YES,那将不会有阴影效果

    4> 设置边框宽度和颜色

    1imageView.layer.borderWidth=5;2imageView.layer.borderColor= [UIColor redColor].CGColor;

    * 第1行设置边框宽度为5

    * 第2行设置边框颜色为红色

    5> 设置旋转

    imageView.layer.transform=CATransform3DMakeRotation(M_PI_4,0,0,1);

    * 利用transform属性可以设置旋转、缩放等效果

    * M_PI_4表示四分之π,顺时针旋转45°

    * 后面的(0, 0, 1)表示Z轴这个向量,修改这个向量可以做一些三维旋转效果,你可以随便改个值试一下,比如(1, 1, 1)

    * 总体的意思是layer会绕着Z轴顺时针旋转45°,也就是在x、y平面进行旋转

    CALayer2-创建新的层

    本文目录

    一、添加一个简单的图层

    二、添加一个显示图片的图层

    三、为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?

    四、UIView和CALayer的选择

    五、UIView和CALayer的其他关系

    *上一讲已经说过,UIView内部默认有个CALayer对象(层),通过layer属性可以访问这个层。要注意的是,这个默认的层不允许重新创建,但可以往层里面添加子层

    *UIView可以通过addSubview:方法添加子视图,类似地,CALayer可以通过addSublayer:方法添加子层

    接下来演示一下如何添加子层:

    回到顶部

    一、添加一个简单的图层

    1CALayer *myLayer =[CALayerlayer];2//设置层的宽度和高度(100x100)3myLayer.bounds= CGRectMake(0,0,100,100);4//设置层的位置5myLayer.position= CGPointMake(100,100);6//设置层的背景颜色:红色7myLayer.backgroundColor=[UIColor redColor].CGColor;8//设置层的圆角半径为109myLayer.cornerRadius=10;1011//添加myLayer到控制器的view的layer中12[self.view.layeraddSublayer:myLayer];

    * 第1行创建了一个自动释放的CALayer对象,你也可以使用经典的alloc和init方法来创建

    * 第12行将创建好的层添加到控制器的view的层中

    回到顶部

    二、添加一个显示图片的图层

    1CALayer *myLayer =[CALayerlayer];2//设置层的宽度和高度(100x100)3myLayer.bounds= CGRectMake(0,0,100,100);4//设置层的位置5myLayer.position= CGPointMake(100,100);6//设置需要显示的图片7myLayer.contents= (id)[UIImage imageNamed:@"lufy.png"].CGImage;8//设置层的圆角半径为109myLayer.cornerRadius=10;10//如果设置了图片,需要设置这个属性为YES才有圆角效果11myLayer.masksToBounds=YES;1213//添加myLayer到控制器的view的layer中14[self.view.layeraddSublayer:myLayer];

    * 在第7行设置需要显示的图片,注意,这里用的是UIImage的CGImage属性,是一种CGImageRef类型的数据

    回到顶部

    三、为什么CALayer中使用CGColorRef和CGImageRef这2种数据类型,而不用UIColor和UIImage?

    * 首先要知道:CALayer是定义在QuartzCore框架中的;CGImageRef、CGColorRef两种数据类型是定义在CoreGraphics框架中的;UIColor、UIImage是定义在UIKit框架中的

    * 其次,QuartzCore框架和CoreGraphics框架是可以跨平台使用的,在iOS和Mac OS X上都能使用,但是UIKit只能在iOS中使用

    * 因此,为了保证可移植性,QuartzCore不能使用UIImage、UIColor,只能使用CGImageRef、CGColorRef

    * 不过很多情况下,可以通过UIKit对象的特定方法,得到CoreGraphics对象,比如UIImage的CGImage方法可以返回一个CGImageRef

    回到顶部

    四、UIView和CALayer的选择

    细心的朋友不难发现,其实前面的2个效果不仅可以通过添加层来实现,还可以通过添加UIView来实现。比如,第1个红色的层可以用一个UIView来实现,第2个显示图片的层可以用一个UIImageView来实现。既然CALayer和UIView都能实现相同的显示效果,那究竟该选择谁好呢?

    * 其实,对比CALayer,UIView多了一个事件处理的功能。也就是说,CALayer不能处理用户的触摸事件,而UIView可以

    * 所以,如果显示出来的东西需要跟用户进行交互的话,用UIView;如果不需要跟用户进行交互,用UIView或者CALayer都可以

    * 当然,CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级

    回到顶部

    五、UIView和CALayer的其他关系

    *UIView可以通过subviews属性访问所有的子视图,类似地,CALayer也可以通过sublayers属性访问所有的子层

    *UIView可以通过superview属性访问父视图,类似地,CALayer也可以通过superlayer属性访问父层

    * 下面再看一张UIView和CALayer的关系图:

    如果两个UIView是父子关系,那么它们内部的CALayer也是父子关系。

    CALayer3-层的属性

    本文目录

    一、隐式动画属性

    二、position和anchorPoint

    回到顶部

    一、隐式动画属性

    * 在前面几讲中已经提到,每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根层)。所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动画。

    * 当对非Root Layer的部分属性进行相应的修改时,默认会自动产生一些动画效果,这些属性称为Animatable Properties(可动画属性)。

    * 列举几个常见的Animatable Properties:

    bounds:用于设置CALayer的宽度和高度。修改这个属性会产生缩放动画

    backgroundColor:用于设置CALayer的背景色。修改这个属性会产生背景色的渐变动画

    position:用于设置CALayer的位置。修改这个属性会产生平移动画

    比如:假设一开始CALayer的position为(100, 100),然后在某个时刻修改为(200, 200),那么整个CALayer就会在短时间内从(100, 100)这个位置平移到(200, 200)

    * 我们也可以从官方文档中查询所有的Animatable Properties

    1.点击Window -> Organizer

    2.在搜索框输入"animatable"即可

    回到顶部

    二、position和anchorPoint

    * position和anchorPoint属性都是CGPoint类型的

    * position可以用来设置CALayer在父层中的位置,它是以父层的左上角为坐标原点(0, 0)

    * anchorPoint称为"定位点",它决定着CALayer身上的哪个点会在position属性所指的位置。它的x、y取值范围都是0~1,默认值为(0.5, 0.5)

    1.创建一个CALayer,添加到控制器的view的layer中

    1CALayer *myLayer =[CALayer layer];2//设置层的宽度和高度(100x100)3myLayer.bounds= CGRectMake(0,0,100,100);4//设置层的位置5myLayer.position= CGPointMake(100,100);6//设置层的背景颜色:红色7myLayer.backgroundColor=[UIColor redColor].CGColor;89//添加myLayer到控制器的view的layer中10[self.view.layer addSublayer:myLayer];

    第5行设置了myLayer的position为(100, 100),又因为anchorPoint默认是(0.5, 0.5),所以最后的效果是:myLayer的中点会在父层的(100, 100)位置

    注意,蓝色线是我自己加上去的,方便大家理解,并不是默认的显示效果。两条蓝色线的宽度均为100。

    2.若将anchorPoint改为(0, 0),myLayer的左上角会在(100, 100)位置

    1myLayer.anchorPoint= CGPointMake(0,0);

    3.若将anchorPoint改为(1, 1),myLayer的右下角会在(100, 100)位置

    1myLayer.anchorPoint= CGPointMake(1,1);

    4.将anchorPoint改为(0, 1),myLayer的左下角会在(100, 100)位置

    1myLayer.anchorPoint = CGPointMake(0,1);

    我想,你应该已经明白anchorPoint的用途了吧,它决定着CALayer身上的哪个点会在position所指定的位置上。它的x、y取值范围都是0~1,默认值为(0.5, 0.5),因此,默认情况下,CALayer的中点会在position所指定的位置上。当anchorPoint为其他值时,以此类推。

    CALayer4-自定义层

    本文目录

    一、自定义层的方法1

    二、自定义层的方法2

    三、其他

    自定义层,其实就是在层上绘图,一共有2种方法,下面详细介绍一下。

    回到顶部

    一、自定义层的方法1

    方法描述:创建一个CALayer的子类,然后覆盖drawInContext:方法,使用Quartz2D API进行绘图

    1.创建一个CALayer的子类

    2.在.m文件中覆盖drawInContext:方法,在里面绘图

    1@implementation MJLayer23#pragmamark 绘制一个实心三角形4- (void)drawInContext:(CGContextRef)ctx {5//设置为蓝色6CGContextSetRGBFillColor(ctx,0,0,1,1);789//设置起点10CGContextMoveToPoint(ctx,50,0);11//从(50, 0)连线到(0, 100)12CGContextAddLineToPoint(ctx,0,100);13//从(0, 100)连线到(100, 100)14CGContextAddLineToPoint(ctx,100,100);15//合并路径,连接起点和终点16CGContextClosePath(ctx);1718//绘制路径19CGContextFillPath(ctx);20}2122@end

    3.在控制器中添加图层到屏幕上

    1MJLayer *layer =[MJLayer layer];2//设置层的宽高3layer.bounds= CGRectMake(0,0,100,100);4//设置层的位置5layer.position= CGPointMake(100,100);6//开始绘制图层7[layersetNeedsDisplay];8[self.view.layer addSublayer:layer];

    注意第7行,需要调用setNeedsDisplay这个方法,才会触发drawInContext:方法的调用,然后进行绘图

    回到顶部

    二、自定义层的方法2

    方法描述:设置CALayer的delegate,然后让delegate实现drawLayer:inContext:方法,当CALayer需要绘图时,会调用delegate的drawLayer:inContext:方法进行绘图。

    * 这里要注意的是:不能再将某个UIView设置为CALayer的delegate,因为UIView对象已经是它内部根层的delegate,再次设置为其他层的delegate就会出问题。UIView和它内部CALayer的默认关系图:

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

    1CALayer *layer =[CALayer layer];2//设置delegate3layer.delegate=self;4//设置层的宽高5layer.bounds= CGRectMake(0,0,100,100);6//设置层的位置7layer.position= CGPointMake(100,100);8//开始绘制图层9[layersetNeedsDisplay];10[self.view.layer addSublayer:layer];

    * 在第3行设置了CALayer的delegate,这里的self是指控制器

    *注意第9行,需要调用setNeedsDisplay这个方法,才会通知delegate进行绘图

    2.让CALayer的delegate(前面设置的是控制器)实现drawLayer:inContext:方法

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

    回到顶部

    三、其他

    1.总结

    无论采取哪种方法来自定义层,都必须调用CALayer的setNeedsDisplay方法才能正常绘图。

    2.UIView的详细显示过程

    * 当UIView需要显示时,它内部的层会准备好一个CGContextRef(图形上下文),然后调用delegate(这里就是UIView)的drawLayer:inContext:方法,并且传入已经准备好的CGContextRef对象。而UIView在drawLayer:inContext:方法中又会调用自己的drawRect:方法

    * 平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由层传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入层的CGContextRef中,然后被拷贝至屏幕

    相关文章

      网友评论

          本文标题:CALayer详细讲解

          本文链接:https://www.haomeiwen.com/subject/bogddxtx.html