iOS CALayer总结——图层几何
最近看了一下关于图层和动画的内容,所以写了一份总结,算是对这些内容的汇总吧,都是一些简单的基础知识,不知道大家都了不了解。
除了和用户的交互之外,图层的很多属性和视图基本上都是一样的,今天就先从CALayer的一些基础的属性入手,没有套路和技巧,只是对属性的介绍:
一、contents
contents是CALayer的一个属性:@property(nullable, strong) id contents;
它的类型是id
,使用contents我们可以为一个普通的图层添加一张图片,但是在赋值的时候,只有CGImageRef
类型才有效,并且需要使用bridged
关键字进行转换,因为CGImageRef并不是一个Cocoa对象,而是一个Core Foundation类型,所有正确的赋值方式为:
UIImage *image = [UIImage imageNamed:@"image_1.jpg"];
self.layerView.layer.contents = (__bridge id)image.CGImage;
效果和使用UIImageView时一样一样的:
和contents相关的还有以下几个属性:
contentsGravity、contentsScale、contentsRect、contentsCenter
contentsGravity
contentsGravity
和UIView的contentMode
属性的作用是相似的,我们可以看到上面的效果图中的图片被拉伸了,我们平时在使用UIImageView展示图片的时候也会出现这种情况,我们设置contentMode
属性就可以解决,在图层中,我们使用contentsGravity
属性就可以了。
contentsGravity
有以下这些可选的值:
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
kCAGravityResize
kCAGravityResizeAspect
kCAGravityResizeAspectFill
值得注意的是:这些值并不是枚举,他们都是常量字符串。
为我们上面的代码再添加一句:
self.layerView.layer.contentsGravity = kCAGravityResizeAspect;
我们可以发现,图片就正常了,效果如下:
contentsScale
contentsScale
属性定义了contents中图片的的像素尺寸和视图大小的比例,它用来判断在绘制图层的时候应该为contents创建的空间大小,和需要显示的图片的拉伸度。如果contentsScale设置为1.0,将会以每个点1个像素绘制图片,如果设置为2.0,则会以每个点2个像素绘制图片,这就是Retina屏幕了。
如果我们已经使用contentsGravity
属性使图片拉伸了,那么我们再设置contentsScale
就会失效(不是所有的contentsGravity的值都会拉伸图片)。
我们先将设置contentsGravity
的代码改为:
self.layerView.layer.contentsGravity = kCAGravityCenter;
然后添加:
self.layerView.layer.contentsScale = image.scale;
我们发现显示的图片跟图片本身大小一致:
我这里使用的是1倍图,如果我们为图片的名字后面添加一个@2x,然后就变成这样了:
原因就不用我多说了吧。
contentsRect
contentsRect
属性规定了我们在contents中可以显示的图片的区域,这个理解起来也很容易,但是要注意的是:contentsRect
不是一个绝对值(点或者像素),而是一个相对值,以左上角为坐标原点,单位坐标在0~1之间,当然也可以是负数。设置了contentsRect
属性只显示左上角1/4区域:
self.layerView.layer.contentsRect = CGRectMake(0, 0, 0.5, 0.5);
效果图如下:
contentsCenter
我们在日常的开发中,有时候UI给的图片我们在显示的时候需要对图片进行拉伸,但是又想只拉伸中间的部分,四周的一些区域不拉伸,我们会使用-resizableImageWithCapInsets:
方法设置一下四周不被拉伸的区域,contentsCenter
属性在图层中起到的也是这个作用,contentsCenter
的默认值是{0, 0, 1, 1},也就是整张图片都被拉伸,如果将值改为{0.25,0.25,0.5,0.5}就表示x,y都从左上角1/4处开始,宽和高分别为图片尺寸的一半大小,所围成的区域被拉伸,其他区域不拉伸。由于我找的图片素材效果不太明显,所有就不贴效果图了。
二、几何属性
在图层的几个几何属性中,我们重点介绍anchorPoint
。
不过在此之前也简单说一下frame
、bounds
、position
,一句话总结:frame
代表了图层的外部坐标(相对于父图层),bounds是内部坐标(相对于自身),position代表了相对于父图层anchorPoint所在的位置。改变图层的bounds
、bounds
和transform
,都会令frame
发生改变。
比如,我们将图层旋转45度,然后看一下旋转前后图层的frame:
NSLog(@"x:%f,y:%f",self.layerView.layer.frame.origin.x,self.layerView.layer.frame.origin.y);
self.layerView.layer.affineTransform = CGAffineTransformMakeRotation(M_PI_4);
NSLog(@"x:%f,y:%f",self.layerView.layer.frame.origin.x,self.layerView.layer.frame.origin.y);
x:112.500000,y:233.500000
x:63.756313,y:209.756313
anchorPoint
上面说到,position代表了相对于父图层anchorPoint所在的位置,通过改变anchorPoint,图层的frame也会发生改变。要理解anchorPoint很容易,直接上代码就很直观了:
创建两个位置和大小都相同的layer,layer1为参照图层,此时两个图层是重合的,
CALayer *layer1 = [[CALayer alloc]init];
layer1.frame = CGRectMake(100, 200, 150, 100);
layer1.backgroundColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:layer1];
CALayer *layer2 = [[CALayer alloc]init];
layer2.frame = CGRectMake(100, 200, 150, 100);
layer2.backgroundColor = [UIColor greenColor].CGColor;
[self.view.layer addSublayer:layer2];
NSLog(@"frame:{%.0f,%.0f,%.0f,%.0f}",layer2.frame.origin.x,layer2.frame.origin.y,layer2.frame.size.width,layer2.frame.size.height);
NSLog(@"bounds:{%.0f,%.0f,%.0f,%.0f}",layer2.bounds.origin.x,layer2.bounds.origin.y,layer2.bounds.size.width,layer2.bounds.size.height);
NSLog(@"positon:{%.0f,%.0f}",layer2.position.x,layer2.position.y);
NSLog(@"anchorPoint:{%.0f,%.0f}",layer2.anchorPoint.x,layer2.anchorPoint.y);
改变layer2的anchorPoint为{0,0}:
layer2.anchorPoint = CGPointMake(0, 0);
anchorPoint是在做图层变换和动画的时候,非常重要的一个属性,它是图层变换的一个把柄,比如图层在做旋转的时候,就是以anchorPoint为基点旋转的。实际上,在UIView中也有anchorPoint,只不过,系统并没有暴露这个属性,UIView的center属性和图层的position属性是同一个概念,anchorPoint默认是{0.5,0.5},所以UIView得center就是中心点了。
zPosition
CALaye
r存在于一个三维空间当中,它还有一个用来表示图层在Z轴方向上位置的属性zPosition
,默认为0,如果改变这个属性,就会改变多个图层之间的显示顺序。就用上面的例子演示一下,改变红色图层的zPosition
,图层是一个非常非常薄的东西,所以我们只需要为zPosition
设置一个比较小的值就可以了,比如说:1.0:
layer1.zPosition = 1.0f;
这样,两个图层的顺序就发生了改变,不过需要注意的是:这只是用户视角上看起来两个图层的顺序改变了,实际上两个图层在父图层上还是原来的顺序。
关于设置图层效果的属性,相信大家其实再熟悉不过了:
比如:圆角(conrnerRadius
)、边框(borderWidth
、borderColor
)、阴影(shadowColor
、shadowOffset
、shadowRadius
、shadowOpacity
)、
图层蒙版(mask
),在这里,就不啰嗦了,还需要节省时间,在接下来的文章中去总结更多更丰富的关于图层的内容。
iOS CALayer总结——图层几何的更多相关文章
- iOS - CALayer 绘图层
1.CALayer 绘图层 在 iOS 系统中,你能看得见摸得着的东西基本上都是 UIView,比如一个按钮.一个文本标签.一个文本输入框.一个图标等等,这些都是 UIView.其实 UIView 之 ...
- iOS开发UI篇—CAlayer(创建图层)
iOS开发UI篇—CAlayer(创建图层) 一.添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控 ...
- iOS - CALayer相关(CATransform3D)
一.图层的几何 图层的几何简单通俗,图层的所有几何属性(包括矩阵变换),都可以有隐式和显式动画. 图层几何的属性: 1.position是CGPoint值,她指定图层相对于她图层的位置,该值基于父图层 ...
- IOS CALayer的属性和使用
一.CALayer的常用属性 1.@propertyCGPoint position; 图层中心点的位置,类似与UIView的center:用来设置CALayer在父层中的位置:以父层的左上角为原点( ...
- [iOS Animation]-CALayer 专用图层
专用图层 复杂的组织都是专门化的 Catharine R. Stimpson 到目前为止,我们已经探讨过CALayer类了,同时我们也了解到了一些非常有用的绘图和动画功能.但是Core Animati ...
- IOS第18天(2,CALayer自定义图层)
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...
- IOS CALayer基本使用 (图层)
● 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个图层(CALayer) ● 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView 的l ...
- ios开发之图层与核心动画一:图层CALayer的认识
#import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutl ...
- iOS CALayer应用详解
跟着大神一起进步,本篇博客原文地址:http://blog.csdn.net/hello_hwc?viewmode=contents 一 CALayer是什么? Layers是绘图和动画的基础, L ...
随机推荐
- python-learning-第二季-画图matplotlib
https://www.bjsxt.com/down/8468.html 绘制方法: 绘制直线: #coding:utf- import matplotlib.pyplot as plt #准备绘制的 ...
- linux非root用户安装jdk1.8
如题,先到 Oracle 官方网站 下载1.8版本的 JDK 压缩包(jdk-8u221-linux-x64.tar.gz)到本地(如D盘的soft目录),然后开始进入linux的非root用户(如w ...
- ES6深入浅出-8 新版的类(下集)-3.书籍推荐
- 敏感信息直接在 nginx 通过环境变量设置
通常我们在维护PHP线上项目的时候,为了隔离配置和代码,会使用fastcgi_param的形式将环境变量定义在Nginx的配置文件中(Apache可以使用SetEnv指令).这样在PHP-FPM运行过 ...
- Flink统计当日的UV、PV
Flink 统计当日的UV.PV 测试环境: flink 1.7.2 1.数据流程 a.模拟数据生成,发送到kafka(json 格式) b.flink 读取数据,count c. 输出数据到kafk ...
- 一个php创建webservice,并通过c#调用的真实实例(转)
https://www.cnblogs.com/sequh/archive/2015/09/18/4819832.html 最近需要用php创建webservice供C#和JAVA来调用,通过3天的搜 ...
- mysql的HA及openstack和k8s区别
数据库HA(Hight Availability) mysql自身支持主主/主备部署,多主(>2),一主多备 galera mariadb集群:多主相互备份 修改容器的启动配置 修改Docker ...
- Flask项目中使用mysql数据库启动项目是发出警告
Flask项目中使用mysql数据库启动项目是发出警告: Warning: (1366, "Incorrect string value: '\xD6\xD0\xB9\xFA\xB1\xEA ...
- transform-transition-animation(1)
网布就是我们的屏幕,x轴沿屏幕平行的水平方向,y轴沿屏幕平行的垂直方向,z轴沿与屏幕垂直方向. rotateX(angle), rotateY(angle), rotateZ(angle), rota ...
- LeetCode 141. 环形链表(Linked List Cycle) 19
141. 环形链表 141. Linked List Cycle 题目描述 给定一个链表,判断链表中是否有环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 ...