iOS CALayer 基础

一、CALayer简介

Core Animation是跨平台的,支持iOS环境和Mac OS X环境凡是支持跨平台的框架,都不能直接使用UIKit框架,因为UIKit框架只能应用在iOS而不能用于Mac需要先理解CALayer,因为核心动画操作的对象是CALayer,而不是UIView。CALayer是核心动画的基础,可以做圆角、阴影、边框等效果。每个UIView内部都有一个Layer的属性。在实现核心动画时,本质上是将CALayer中的内容转换成位图(一种图像格式),从而便于图形硬件的操纵。

二、UIView的CALayer基本属性

设置UIView中的CALayer属性,圆角、边框、阴影及3D形变属性。在UIView中CALayer只是一个类声明,需要添加QuartzCore框架,在使用颜色时,不能直接使用UIColor而需要将颜色转成CGColor。修改图层相当于修改UIView属性,即修改了界面属性,要设置阴影,需要同时指定阴影的偏移尺寸、颜色和透明度,形变属性既可以用形变函数指定,也可以用keyPath指定

三、UIImageView的CALayer基本属性

设置UIImageView中的CALayer属性,圆角、边框、阴影。UIImageView中不仅一个子图层,因此设置圆角时需要使用setMasksToBounds:YES,让所有子图层跟随边框,不过设置该属性后,无法使用阴影效果,可以在底层附加一个UIView实现阴影效果,设置UIImageView中的CALayer属性,transform属性可以调整CALayer的形变,其中包括:旋转、缩放、平移,transform属性的参数查询:CATransform

四、图层和视图之间的关系

创建视图对象时,视图会自己创建一个层,视图在绘图(如drawRect:)时,会将内容画在自己的层上。当视图在层上完成绘图后,系统会将图层拷贝至屏幕(CALayer绘图的上下文是图像,整个画完后,才显示,提前绘制提高性能以及用户体验)。每个视图都有一个层,每个图层又可以有多个子层,Layer的设计目的不是为了取代视图,不能基于CALayer创建一个独立的可视化组件。Layer的设计目的是提供视图的基本可视内容,以便提高动画的执行效率,除提供可视内容外,Layer不负责视图的事件响应等工作,同时Layer不能参与到响应者链条中。

五、CALayer的使用说明

通过UIView的layer属性可以拿到对应的根层,这个层不允许重新创建,但可以往层里面添加子层(调用CALayer的addSublayer)要具体使用CALayer,需要引入<QuartzCore/QuartzCore.h>,获取当前图层或使用静态方法layer初始化CALayer后,可以设置以下属性
bounds:宽度和高度
position:位置(默认指中心点,具体由anchorPoint决定)
anchorPoint:锚点(x,y的范围都是0-1),决定了position的含义
backgroundColor: 背景颜色(CGColorRef类型)
borderColor:边框颜色(CGColorRef类型)
borderWidth:边框宽度
cornerRadius:圆角半径
contents: 内容(比如设置为图片CGImageRef)
虽然CALayer可以使用frame,但最好还是使用bounds和position。为层设置动画时,用bounds和position会方便一点

六、创建自定义图层

创建自定义图层,并设置以下属性:
bounds:宽度和高度
backgroundColor: 背景颜色(CGColorRef类型)
position:位置(默认指中点,具体由anchorPoint决定)
anchorPoint:锚点(x,y的范围都是0-1),决定了position的含义
contents:内容CGImageRef
锚点和位置的关系,以及在旋转转换时对图层的影响,UIView有一个addSubview方法,而layer有一个addSubLayer方法,锚点在游戏开发中使用比较频繁,而在应用开发中极少使用

七、CALayer中图像及颜色的注意事项

CALayer中使用CGColorRef和CGImageRef的数据类型,而不用UIColor和UIImage,QuartzCore(包含CALayer类)和Core Graphics(包含CGImageRef、CGColorRef)框架都能在iOS和Mac OS X上使用,但是UIKit(包含UIImage和其他UI开头的类)只能在iOS中使用,为了保证可移植性,QuartzCore不能使用UIImage,只能使用CGImageRef,不过很多情况下,可以通过UIKit对象的特定方法,可以得到Core Graphics对象,如UIImage的CGImage方法和UIColor的CGColor方法。

八、CALayer的隐式动画属性

每一个UIView内部都默认关联着一个CALayer,称这个Layer为Root Layer。所有的非Root Layer都存在着隐式动画,隐式动画的默认时长为1/4秒。当修改非Root Layer的部分属性时,相应的修改会自动产生动画效果,能执行隐式动画的属性被称为“可动画属性”,诸如:
bounds: 缩放动画
position: 平移动画
opacity: 淡入淡出动画(改变透明度)
在API中搜素animatable可以找到所有可动画属性,如果要关闭默认的动画效果,可以通过动画事务方法实现:
[CATransaction begin];
[CATransaction setDisableActions:YES];
[CATransaction commit];

九、CALayer、UIView以及上下文之间的关系

当UIView收到setNeedsDisplay消息时,CALayer会准备好一个CGContextRef,然后向它的delegate即UIView,发送消息,并且传入已经准备好的CGContextRef对象。UIView在drawLayer:inContext:方法中会调用自己的drawRect:方法,平时在drawRect:中通过UIGraphicsGetCurrentContext()获取的就是由CALayer传入的CGContextRef对象,在drawRect:中完成的所有绘图都会填入CALayer的CGContextRef中,然后被拷贝至屏幕,CALayer的CGContextRef用的是位图上下文(Bitmap Graphics Context)

十、获取CALayer中的内容——截屏

UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
说明:使用renderInContext方法可以将指定图层及其子图层中的内容渲染输出到指定的上下文中

十一、CALayer绘图

使用Quartz 2D绘图,是直接调用UIView的drawRect:方法绘制图形、图像,这种方式的本质还是再图层中绘制。drawRect:方法是由UIKit组件进行调用,因此厘米那可以使用到一些UIKit封装的方法进行绘制,而直接绘制到图层的方法由于并非UIKit直接调用因此只能用原生的Core Graphics方法绘制,图层绘制有两种方法,不管使用那种方法绘制完必须调用图层的setNeedDisplay方法,下面介绍图层的两种绘制方法:
1)、通过图层代理drawLayer:inContext:方法绘制
通过代理方法进行图层呢个绘制只要指定图层的代理,然后在代理对象中重写 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;方法即可。需要注意这个方法虽然是代理方法但是不用手动实习那CALayerDelegate,因为CALayer定义中给NSObject做了分类扩展,所有的NSObject都包含这个方法。无论使用哪种方法,都必须向层发送 - (void)setNeedsDisplay;方法,否测绘制内容无法显示。
2)、使用自定义图层绘图
在自定义图层绘图时只要自己编写一个类继承与CALayer然后在 - (void)drawInContext:(CGContextRef)ctx;中绘图即可。同前面在代理方法绘图一样,要显示图层中绘制的内容也要调用图层的 - (void)setNeedsDisplay;方法,否则 - (void)drawInContext:(CGContextRef)ctx;方法将不会调用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容