CALayer及其子类
前言:这个系列要更新Core Animation的内容,但是CALayer是Core Animation的基础。
一 CALayer是什么?
摘自官网的一句话-Layers Provide the Basis for Drawing and Animations(Layers是绘图和动画的基础)
Layer是在3D空间中的2D平面。Layer管理的几何(例如rotate,transfrom),内容(image等),和可视属性 (backgroundColor,alpha)等信息。Layer主要通过管理bitmap来维护自己的状态信息,从这一点上来说,Layer可以看作 对象模型,因为他们主要用来管理数据。
Layer是基于bitmap的,它会捕获View要呈现的内容,然后cache在一个bitmap中,这个bitmap可以看作一个对象。这样每次进行操作,例如平移旋转等,只是bitmap的矩阵运算。基于Layer的动画过程如图
由于基于Layer的绘制是处理静态的Bitmap的,而bitmap的处理又是GPU所擅长的,所以它的效率要比基于View绘制的高很多,因为基于View绘制的每次都要进行drawRect的调用重新绘制。
二 Layer支持继承,支持添加Sublayer,支持对sublayer进行层次调整
常用的Layer子类
CAEmitterLayer |
发射器层,用来控制粒子效果 |
CAGradientLayer |
梯度层,颜色渐变 |
CAEAGLayer |
用OpenGL ES绘制的层 |
CAReplicationLayer |
用来自动复制sublayer |
CAScrollLayer |
用来管理可滑动的区域 |
CAShapeLayer |
绘制立体的贝塞尔曲线 |
CATextLayer |
可以绘制AttributeString |
CATiledLayer |
用来管理一副可以被分割的大图 |
CATransformLayer |
用来渲染3D layer的层次结构 |
管理Layer内容的几个函数
三 直接设置UIView的Layer
先看一个示例,然后我会列出常用的属性,最后就某几个比较不容易理解的属性单独分析。
先在Stroyboard上拖拽一个UIView,然后control+drag出一个IBOutlet,命名为containView
@property (weak, nonatomic) IBOutlet UIView *containView;
然后,在ViewDidLoad中,键入如下代码
containView.layer.backgroundColor = [UIColor lightGrayColor].CGColor;//背景色
containView.layer.cornerRadius = 20.0;//圆角
containView.layer.shadowColor = [UIColor blueColor].CGColor;//阴影颜色
containView.layer.shadowOpacity = 0.8;//阴影透明度
containView.layer.shadowOffset = CGSizeMake(3.0, 3.0);//阴影的偏移量
containView.layer.borderColor = [UIColor redColor].CGColor;//边界颜色
containView.layer.borderWidth = 2;//边界宽度
这样,运行后的效果如图
四 添加Sublayer
containView.layer.backgroundColor = [UIColor lightGrayColor].CGColor;
containView.layer.cornerRadius = 20.0;
containView.layer.shadowColor = [UIColor blueColor].CGColor;
containView.layer.shadowOpacity = 0.8;
containView.layer.shadowOffset = CGSizeMake(3.0, 3.0);
containView.layer.borderColor = [UIColor redColor].CGColor;
containView.layer.borderWidth = 2; CALayer * sublayer1 = [CALayer layer];
sublayer1.backgroundColor = [UIColor blueColor].CGColor;
sublayer1.frame = CGRectMake(0, 0,80,80);
sublayer1.anchorPoint = CGPointMake(0.5, 0.5);
sublayer1.position = CGPointMake(100,100);
[containView.layer addSublayer:sublayer1];
效果图如图
有可能添加Sublayer的时候,sublayer的frame范围已经超过了super Layer的frame,那么会怎么样呢?
sublayer1.position = CGPointMake(0,CGRectGetMaxY(containView.bounds)-10);
修改sublayer1的位置,然后效果如图
但是,很多时候我们并不想sublayer的范围超出 super layer,这时候可以设置这个属性
containView.layer.masksToBounds = YES;
效果如图
这里再听过两个常用的CALayer的子类UIShapeLayer和UITextLayer的示例
CAShapeLayer * shapeLayer = [CAShapeLayer layer];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path,nil,0.0,0);
CGPathAddLineToPoint(path,nil,0.0,CGRectGetHeight(containView.bounds)/2);
shapeLayer.path = path;
shapeLayer.bounds = CGRectMake(0,0,5.0,CGRectGetHeight(containView.bounds)/2);
shapeLayer.anchorPoint = CGPointMake(0.5, 0.5);
shapeLayer.position = CGPointMake(CGRectGetMidX(containView.bounds),CGRectGetMidY(containView.bounds));
shapeLayer.lineWidth = 5.0;
shapeLayer.lineCap = kCALineCapRound;
shapeLayer.strokeColor = [UIColor yellowColor].CGColor;
[containView.layer addSublayer:shapeLayer]; CATextLayer * textLayer = [CATextLayer layer];
NSString * text = @"blog.csdn.net/hello_hwc";
NSAttributedString * attributeString = [[NSAttributedString alloc] initWithString:text];
textLayer.string = text;
textLayer.alignmentMode = @"center";
textLayer.fontSize = 12;
textLayer.foregroundColor = [UIColor brownColor].CGColor;
CGRect bounds;
bounds.origin = CGPointMake(0, 0);
bounds.size = attributeString.size;
textLayer.bounds = bounds;
textLayer.position = CGPointMake(100,100);
[containView.layer addSublayer:textLayer];
效果图如图
五 anchorPoint和position
和UIView不同,Layer主要由三个属性来设置位置(极少用Frame):
bounds - 设置大小
anchorPoint -设置锚点(锚点对后续的layer动画有很大影响)
position - 锚点在superLayer中的位置
这样说有点抽象,我们看看以下的图就了解了
对于IOS来说,坐标系如图,archPoint(x,y)的两个值通常取0.0-1.0,默认值是(0.5,0.5)这里的值可以看作所占用x的比例,比如默认的0.5,0.5就是在x的中间和y的中间。
而position则是AnchorPoint在super layer中的位置
如下图
五 Layer显示图片
CALayer * imageLayer = [CALayer layer];
imageLayer.bounds = CGRectMake(0,0,200,100);
imageLayer.position = CGPointMake(200,200);
imageLayer.contents = (id)[UIImage imageNamed:@"lichen.jpg"].CGImage;
imageLayer.contentsGravity = kCAGravityResizeAspect;
[containView.layer addSublayer:imageLayer];
效果图
这里,要详细讲解以下contentGravity这个属性。这个属性决定了contents如何填充。
具体分为两个方面,
方面一,位置方面
具体如图
方面二,比例变换方面
如图
六 Layer于UIView的区别
摘自官方文档
Layers are not a replacement for your app’s views—that is, you cannot
create a visual interface based solely on layer objects. Layers provide
infrastructure for your views. Specifically, layers make it easier and
more efficient to draw and animate the contents
of views and maintain high frame rates while doing so. However, there
are many things that layers do not do. Layers do not handle events, draw
content, participate in the responder chain, or do many other things.
For this reason, every app must still have
one or more views to handle those kinds of interactions.
In iOS, every view is backed by a corresponding layer object but in
OS X you must decide which views should have layers. In OS X v10.8 and
later, it probably makes sense to add layers to all of your views.
However, you are not required to do so and can still
disable layers in cases where the overhead is unwarranted and unneeded.
Layers do increase your app’s memory overhead somewhat but their
benefits often outweigh the disadvantage, so it is always best to test
the performance of your app before disabling layer
support.
简单来说,View和Layer最大的区别就是View可以接受用户输入(例如触摸)而Layer不可以,Layer单独并不能呈现出任何可视的内容,必
须依托于View。Layer只是几何上呈现给用户的东西,它较为轻量,通常采用Cache技术,对资源消耗也较小。
转载:http://doc.okbase.net/Hello_Hwc/archive/123447.html
CALayer及其子类的更多相关文章
- CALayer的子类之CAShapeLayer
一,CAShapeLayer介绍 * CAShapeLayer继承自CALayer,属于QuartzCore框架,可使用CALayer的所有属性. CAShapeLayer是在坐标系内绘制贝塞尔曲 ...
- iOS CALayer应用详解
跟着大神一起进步,本篇博客原文地址:http://blog.csdn.net/hello_hwc?viewmode=contents 一 CALayer是什么? Layers是绘图和动画的基础, L ...
- CALayer 4 详解 -----转自李明杰
CALayer4-自定义层 本文目录 一.自定义层的方法1 二.自定义层的方法2 三.其他 自定义层,其实就是在层上绘图,一共有2种方法,下面详细介绍一下. 回到顶部 一.自定义层的方法1 方法描 ...
- CALayer笔记
1.Core Animation是跨平台的,支持IOS和Mac OS X环境 2.核心动画操作的对象不是UIView而是CALayer,CALayer是核心动画的基础, 可以做圆角.阴影.边框等效果 ...
- iOS:CALayer核心动画层上绘图
在CALayer上绘图: •要在CALayer上绘图,有两种方法: 1.创建一个CALayer的子类,然后覆盖drawInContext:方法,可以使用Quartz2D API在其中进行绘图 2.设置 ...
- OC - 21.CALayer核心要点及实例解析
CALayer基础 CALayer是每一个UI控件的核心,一个UI控件之所以能显示可以说是CALayer的功劳 每一个UI控件默认都为自己创建一个CALayer对象,通过drawRect方法将内容绘制 ...
- iOS基础 - CALayer
一.CALayer简介 Core Animation是跨平台的,支持iOS环境和Mac OS X环境 凡是支持跨平台的框架,都不能直接使用UIKit框架,因为UIKit框架只能应用在iOS而不能用于M ...
- CALayer 进阶
转载自:http://www.cofcool.net/development/2015/06/19/ios-study-note-eight-CALayer-info/ The CALayer cla ...
- [iOS Animation]-CALayer 专用图层
专用图层 复杂的组织都是专门化的 Catharine R. Stimpson 到目前为止,我们已经探讨过CALayer类了,同时我们也了解到了一些非常有用的绘图和动画功能.但是Core Animati ...
随机推荐
- 【cocos2d-x 仙凡奇缘-网游研发(1) 登录&注册】
转载请注明出处:http://www.cnblogs.com/zisou/p/xianfan01.html 公司的项目总算告一段落了,年前憋到年后,总算要上线了,所以我也有了时间来搞我自己的游戏项目了 ...
- flask源码解析之上下文为什么用栈
楔子 我在之前的文章<flask源码解析之上下文>中对flask上下文流程进行了详细的说明,但是在学习的过程中我一直在思考flask上下文中为什么要使用栈完成对请求上下文和应用上下文的入栈 ...
- docker镜像基本操作一
获取镜像 首先说明一下如何从Docker hub中获取高质量的镜像,从Docker镜像库获取镜像的命令是docker pull .其命令格式为: docker pull [选项] [Docker Re ...
- JVM概念总结:数据类型、堆与栈
Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身: 引用类型的变量保存引用值,引用值代表了某个对象的引用而不是对象的本身,对象的本身存放 ...
- 《JAVA与模式》之桥梁模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述桥梁(Bridge)模式的: 桥梁模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式. ...
- vue项目打包后路径出错
安装完vue后搭建了一个项目,直接执行 npm run dev 是可以正常打开页面的: 但是执行 npm run build 打包项目后打开却报错了,如下: 原来是项目中的静态文件路径报错了... 然 ...
- Opencv --- 图像像素遍历的各种方法
#include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgu ...
- Ubuntu16.04 Nvidia驱动、CUDA安装
安装Nvidia驱动和CUDA时往往很费力,经常有莫名奇妙的错误,这次安装十分顺畅,权当记录一下,以方便以后再次安装. 一.Nvidia显卡驱动安装 sudo add-apt-repository p ...
- ajax--底层代码
ajax:Asynchronous JavaScript And XML,异步的js与XML.ajax并不是一种新的编程语言,而是一种使用现有标准的新方法.ajax能够在不重载整个网页的情况下与服务器 ...
- diskpart 格式化u盘 制作u盘启动盘方法
1.cmd 2.diskpart 3.list disk 4.select disk [index] 注:[index] 磁盘索引号 5.clean 6.create partition prim ...