CoreAnimation 图层几何学
CoreAnimation 图层几何学
博客园MakeDown支持不佳,如有需要请进GitHub
图层几何所讲主要是有关图层的位置,尺寸等几何类属性.
布局
在UIView中与位置,尺寸有关的属性有 frame bounds center在此不多赘述,在CALayer中同样有与其相对应的属性 frame bounds position 需要注意的是 center与position 虽然字面表达不一样,但是其功能是一致的,为了更加清晰的展示以上内容,我在故事板中创建一个有色UIView.

图片一
在控制台打印日志:
customView_frame:{{117, 241}, {140, 185}}
customView_bounds:{{0, 0}, {140, 185}}
customView_center:{187, 333.5}
customView_layer_frame:{{117, 241}, {140, 185}}
customView_layer_bounds:{{0, 0}, {140, 185}}
customView_layer_position:{187, 333.5}
根据日志所打印内容可知 UIView与CALayer 的布局属性是一一对应的.
以上内容了解后我们需要直达frame本质上是一个复合的属性,也就是说他是由bounds position transform计算得到的(transform:放大,旋转等).为了证实这件事,我们将上面的有色View旋转一个角度.

图片二
在控制台打印日志:
customView_layer_frame:{{80.128221735089298, 218.39265014993941}, {213.74355652982138, 230.21469970012117}}
customView_layer_bounds:{{0, 0}, {140, 185}}
customView_layer_position:{187, 333.5}
通过对比两次打印日志的对比不难发现,当我们将图层旋转后 bounds position 都没有改变,而 frame 却大有改变.那么问题来了,此时的 frame 代表的是什么?我们以customView_layer_frame为 frame 在视图上添加一个新的视图并且将其作为旋转视图的背景.

图片三
图片三与图片二相比我们可以发现,`frame`实际上代表了覆盖在图层旋转之后的整个轴对齐的矩形区域.
锚点-anchorPoint
锚点这个词初识是很陌生的,好比航船的锚用来固定航船,图层中的锚点也具有相同的功能,锚点可以 固定 图层,也就是说锚点是图层的句柄.默认情况下锚点位于图层的中点,我们将图二的的锚点打印.
customView_layer_anchorPoint:{0.5, 0.5}
我了便于观察,我在已有的 UIView 上面添加一个同样大小位置显色不同的UIView(在橙色视图上面添加一个绿色视图,绿色视图的锚点在绿色视图的中心点).

图片四
将绿色视图的锚点设置为(0.0).
绿色视图的锚点在绿色视图的左上角.

图片五
再做一次实现,我将绿色视图的锚点设置为(1,1).也就是将锚点设置在绿色视图的右下角.

图片六
改变锚点可以盖面绿色视图的展示效果,那么此时的 bounds position frame 呢?我在控制台打印锚点为(0.5,0.5)与(1,1)时的数据.
//(0.5,0.5)
customView_layer_frame:{{0, 0}, {140, 185}}
customView_layer_bounds:{{0, 0}, {140, 185}}
customView_layer_position:{70, 92.5}
//(1,1)
customView_layer_frame:{{-70, -92.5}, {140, 185}}
customView_layer_bounds:{{0, 0}, {140, 185}}
customView_layer_position:{70, 92.5}
由两个数据对比可得,锚点的改变只会改变 frame.
到此锚点的基本概念已经基本了解,那么锚点用在什么地方呢?在这我列举一个简单的用法.现在我将锚点为(0.5,0.5)与(1,1)的绿色视图分别进行旋转(持续).

图片七

图片八
对比两个GIF,可以知道视图的旋转是以锚点为中心进行旋转的.
坐标系
坐标系无非就是(x,y,z),我不对(x,y)进行讲解,着重讲解一下z.在视图坐标系中,z轴与我们在数学中的z轴是有相同的效果的,他表现的是垂直的坐标,如果我们为图层设置z轴坐标该图层将会在未设置z轴坐标或者小于该z轴坐标的图层上方展示.为了着重表现该现象,我在绿色视图中添加一个蓝色图层与红色图层,先看一下代码清单.
CALayer * blueLayer = [[CALayer alloc]init];
blueLayer.frame = self.greenView.layer.frame;
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
CALayer * redLayer = [[CALayer alloc]init];
redLayer.frame = self.greenView.layer.frame;
redLayer.backgroundColor = [UIColor redColor].CGColor;
[self.greenView.layer addSublayer:blueLayer];
[self.greenView.layer addSublayer:redLayer];
由代码可以发现先添加的蓝色图层后添加的红色图层,因此红色图层在最上方.

图片九
将蓝色的图层的z轴坐标设置为1.0f.

图片十
Hit Testing
CALayer 是不关心响应链事件的,但是它提供了两个方法来处理事件.
- -containsPoint:
- -hitTest:
-containsPoint: 接受一个在本图层坐标系下的CGPoint,如果这个点在图层frame范围内就返回YES,否则返回NO.为了理解这一性质我写一个小案例,在以后的蓝色图层和白色图层中点击,如果点击蓝色区域控制台打印blue,如果在白色区域控制台打印white.
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
CGPoint point = [[touches anyObject]locationInView:self.view];
point = [self.blueLayer convertPoint:point fromLayer:self.view.layer];
if ([self.blueLayer containsPoint:point]) {
NSLog(@"blue");
}else{
NSLog(@"white");
}
}
-hitTest: 也是接受一个 CGPoint 但是返回的是 CALayer,通过判断返回的图层是否是所要响应的图层然后做出相应的操作,继续上面的案例稍加改动.
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
CGPoint point = [[touches anyObject]locationInView:self.view];
CALayer * layer = [self.view.layer hitTest:point];
if (layer == self.blueLayer) {
NSLog(@"blue");
}else{
NSLog(@"white");
}
}
自动布局
当使用视图的时候,可以充分利用UIView的UIViewAutoresizingMask和NSLayoutConstraint进行自动布局,但是如果想要随意控制CALayer的布局,就需要通过使用 CALayerDelegate .如下函数:
- (void)layoutSublayersOfLayer:(CALayer *)layer;
当图层的bounds发生改变,或者图层的-setNeedsLayout方法被调用的时候,这个函数就会执行.这时可以手动的对图层进行重新绘制,但是不能像UIView的autoresizingMask和constraints属性做到自适应屏幕旋转.这也是为什么最好使用视图而不是单独的图层来构建应用程序的重要原因之一.
CoreAnimation 图层几何学的更多相关文章
- CoreAnimation1-图层树、寄宿图以及图层几何学
(一)图层的树状结构 Core Animation其实是一个令人误解的命名.你可能认为它只是用来做动画的,但实际上它是从一个叫做Layer Kit这么一个不怎么和动画有关的名字演变而来,所以做动画这只 ...
- [iOS Animation]-CALayer 图层几何学
图层几何学 不熟悉几何学的人就不要来这里了 --柏拉图学院入口的签名 在第二章里面,我们介绍了图层背后的图片,和一些控制图层坐标和旋转的属性.在这一章中,我们将要看一看图层内部是如何根据父图层和兄弟图 ...
- CoreAnimation 目录
CoreAnimation 目录 CoreAnimation 开篇 CoreAnimation 寄宿图 CoreAnimation 图层几何学 CoreAnimation 视觉效果
- 【CoreAnimation】1 到 5
学习资源来自:图层树 . Quartz 2D Core Animation 复合引擎,职责为尽可能快地组合屏幕上不同的可视内容.这些内容被分解成多个独立的图层,存储在 图层树 的体系中.于是这个树形成 ...
- CoreAnimation3-专用图层
CAShapeLayer CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类.你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自 ...
- [iOS Animation]-CALayer 专用图层
专用图层 复杂的组织都是专门化的 Catharine R. Stimpson 到目前为止,我们已经探讨过CALayer类了,同时我们也了解到了一些非常有用的绘图和动画功能.但是Core Animati ...
- CoreAnimation6-基于定时器的动画和性能调优
基于定时器的动画 定时帧 动画看起来是用来显示一段连续的运动过程,但实际上当在固定位置上展示像素的时候并不能做到这一点.一般来说这种显示都无法做到连续的移动,能做的仅仅是足够快地展示一系列静态图片,只 ...
- CoreAnimation5-图层时间和缓冲
图层时间 动画的发生是需要持续一段时间的,所以计时对整个概念来说至关重要.在这一章中,我们来看看CAMediaTiming,看看Core Animation是如何跟踪时间的. CAMediaTimin ...
- 【转】iOS-Core-Animation-Advanced-Techniques(六)
原文:http://www.cocoachina.com/ios/20150106/10839.html 基于定时器的动画和性能调优 基于定时器的动画 我可以指导你,但是你必须按照我说的做. -- 骇 ...
随机推荐
- SpringMvc项目中使用GoogleKaptcha 生成验证码
前言:google captcha 是google生成验证码的一个工具类,其原理是将随机生成字符串保存到session中,同时以图片的形式返回给页面,之后前台页面提交到后台进行对比. 1.jar包准备 ...
- Java错题
加粗为正确答案,绿色为错选答案 1.对于以下代码: for ( int i=0; i<10; i++) System.out.println(i); for循环后,i的值是多少? A.i不再存 ...
- DllRegisterServer的调用失败的问题解决方法
1'按键盘上的win+x键调出常用命令. 2'选择“命令提示符(管理员)“ 3'在”命令提示符“中输入”regsvr32 c:\Windows\SysWOW64\comdlg32.ocx“或其他ocx ...
- 用 Lua 实现一个微型虚拟机-基本篇
用 Lua 实现一个微型虚拟机-基本篇 目录 介绍 机器指令模拟 最终核心代码 虚拟机内部状态可视化 完整项目代码 后续计划 参考 介绍 在网上看到一篇文章 使用 C 语言实现一个虚拟机, 这里是他的 ...
- stringBuffer的使用及字符串比较的区别
/* * 关于equals()和==: 对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true; * 而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的 ...
- 纯css实现京东导航菜单
纯CSS代码实现导航菜单,推荐在chrome预览! 预览请点击这里:mygithub <!doctype html> <html lang="en"> &l ...
- nginx.conf完整配置实例
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; ...
- java从入门到卖肠粉系列
java从入门到卖肠粉系列 注:本教程只是从JAVA基础开始,绝对不会跟公司有任何利益冲突,更不会出现一行公司项目的代码 QQ群:9547527 推荐用土豆,百度去上传太慢,百度云在线播放还要转码.. ...
- [.NET] RabbitMQ 的行为艺术
RabbitMQ 的行为艺术 序 好像,今天已经是 2 月 28 号了. 听说,29.30.31 号放假. 据说,有图,有真相. 目录 简介 环境搭建 示例一:简单的 Hello World 示例二: ...
- 关于ReentrantLock和Condition的用法
这篇博客是过年后的第一篇博客,2.13正式上班,之前在家休年假.上班第一天公司说有个紧急的项目需要上线,所以我们连续加了两个星期的班,直到上个周六还在加班,终于成功上线了.今天是2月的最后的一天,继续 ...