如人饮水,冷暖自知

iOS 模块详解—「Core Animation 之 CALayer 图层」

引导


本篇文章主要从【Core Animation 之 CALayer】学习总结,该模块学习将续更 ~
在「时间 & 知识 」有限内,总结的文章难免有「未全、不足 」的地方,还望各位好友指出,可留言指正或是补充,以提高文章质量@白开水ln原著;

目录:

  1. UIView和CALayer的类定义
  2. UIView和CALayer的区别和选择
  3. CALayer的基本操作
  4. CATransform3D
  5. CGAffineTransform
  6. 真正的高阶技巧 iOS Core Animation
  7. SourceCodeToolsClassWechatPublic-Codeidea

1.UIView和CALayer的类定义


1.CALayer的介绍
CALayer 是定义在 QuartzCore 框架中,从下图可以看出UIView内部定义了一个CALayer对象,它是用来在屏幕上显示内容展示的矩形区域;
CALayer是个与UIView很类似的概念,同样有backgroundColor、frame等相似的属性,我们可以将UIView看做一种特殊的CALayer。但实际上UIView是对CALayer封装,在CALayer的基础上再添加交互功能。UIView的显示必须依赖于CALayer。我们同样可以跟新建view一样新建一个layer,然后添加到某个已有的layer上,同样可以对layer调整大小、位置、透明度等。一layer可以有两种用途一是对view相关属性的设置,包括圆角、阴影、边框等参数;二是实现对view的动画操控。因此对一个view进行动画,本质上是对该view的.layer进行动画操作;

UIView内部CALayer对象.png

2.UIView和CALayer的区别和选择

UIView和CALayer区别
1.在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),CALayer 在背后提供内容的绘制和显示;两者都有树状层级结构,layer 内部有 SubLayers,View 内部有 SubViews.但是 Layer 比 View 多了个AnchorPoint(锚点)

2.当UIView需要显示到屏幕上时(UIView 做为 Layer 的 CALayerDelegate,View 显示内容由CALayer 的 display),会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成了UIView的显示。
换句话说,UIView本身不具备显示的功能,是因为它内部的图层(CALayer)才有显示功能

3.Layer 的 frame 是由它的 bounds、position、anchorPoint 和 transform 共同决定的;View 的 frame 只是简单的返回 Layer的 frame,同样 View 的 bounds 和 center 也是返回 Layer 的一些属性。

4.UIView 多了一个事件处理的功能,也就是说 UIView 可以处理用户的触摸事件,而 CALayer 不可以

UIView和CALayer选择
通过CALayer,也能做出和 UIImageView 一样的效果,相比较UIView多了一个事件处理的功能;

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

当然,CALayer 的性能会高一些,因为它少了事件处理的功能,更轻量级(实际开发中还是建议使用UIView,可扩展性强);

2.CALayer的基本操作

1.CALayer的常用属性

属性 描述
bounds 图层大小
position 图层中心点位置,相当于UIView的center
opacity 透明度,相当于UIView的alpha
anchorPoint 和中心position重合的点,称为锚点,范围在(0~1,0~1),默是(0.5,0.5)
contents image添加到layer的contents
opacity 透明度,相当于UIView的alpha
contentsRect 设置图片显示的尺寸,取值0~1(x0, y0, W1, H1),如 CGRectMake(0, 0, 1, 0.5);只将图像的上半部分显示在整个layer中;
CATransform3D 形变属性(设置平移、缩放和旋转时的 3D效果)
cornerRadius / masksToBounds 圆角半径 / 属性为YES才显示圆角效果

2.创建自定义的CALayer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// layer基本使用
- (void)layerWithUIView{
 // 自定义图层
    CALayer *layer = [CALayer layer];
    layer.bounds = CGRectMake(00100100);
    layer.contents = (id)[UIImage imageNamed:@"阿狸头像"].CGImage;?
    layer.backgroundColor = [UIColor redColor].CGColor;?
    layer.position = self.view.center;
    layer.anchorPoint = CGPointMake(0.51);
    // 默认是自带阴影的效果, 默认为0.
    self.redView.layer.shadowOpacity = 1;
    // 添加图层到根图层
    [self.view.layer addSublayer:layer];
    ***********其它属性**************** 
    
    // 设置阴影的颜色
    layer.shadowColor = [UIColor blackColor].CGColor;
    // 设置阴影的偏移量((x,y) 例:右下)
    layer.shadowOffset = CGSizeMake(1010);
    // 设置阴影的模糊程度
    layer.shadowRadius = 10;
    // 设置边框的宽度(注意:是往里面走的) 和 颜色
    layer.borderWidth = 5;
    layer.borderColor = [UIColor blueColor].CGColor;
    
    // 设置圆角半径
    layer.cornerRadius = 50;
    // 图层中绘制的图片无法正确显示,解决:把超过根层以外的东西剪切掉(UIView自带的层,我们称为是根层)
    layer.masksToBounds = YES;
    
    // 设置图层的代理
    layer.delegate = self;
    // setNeedsDisplayh会调用drawRect:方法
    [layer setNeedsDisplay];
}
``` 
注解:
- 1、阴影效果无法 和 `masksToBounds`同时使用;
- 2、裁剪:`masksToBounds` 是 `CALayer` 的属性;`clipsToBounds` 是 `UIView` 的属性;
- 3、`CGImage` 和 `CGColor` 的解释:
- `CALayer`是定义在`QuartzCore`框架中的
`CGImageRef`、`CGColorRef`两种数据类型是定义在`CoreGraphics`框架中的
- `UIColor`、`UIImage`是定义在`UIKit`框架中的
`QuartzCore`框架和`CoreGraphics`框架是可以跨平台使用的,在`iOS`和`Mac OS X`上都能使用,但是`UIKit`只能在`iOS`中使用,为了保证可移植性,`QuartzCore`不能使用`UIImage`、`UIColor`,只能使用`CGImageRef`、`CGColorRef`,即需要:`.CGImage` 和 `.CGColor`.
#### 3.CATransform3D
>注意:使用KVC快速设置时,Key Paths值一定不要写错
```objc
// 触摸开始调用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// CATransform3D,设置平移、缩放和旋转时的 3D效果
[UIView animateWithDuration:1 animations:^{
// 方式一:CATransform3D普通设置
// 平移 (CGFloat sx, CGFloat sy, CGFloat sz)
self.imageView.layer.transform = CATransform3DTranslate(self.imageView.layer.transform, 10, 0, 0);
// 缩放
self.imageView.layer.transform = CATransform3DScale(self.imageView.layer.transform, 1.2, 1.2, 0);
// 旋转
self.imageView.layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
// 方式二:CATransform3D KVC快速设置
// 把结构体转成对象
//NSValue *value = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0, 0, 1)];
//[self.imageView.layer setValue:value forKeyPath:@"transform"];
// 通过KVC快速平移(translation)、缩放(sacle)、旋转(rotation)
// 平移
[self.imageView.layer setValue:@(100) forKeyPath:@"transform.translation.y"];
// 缩放
[self.imageView.layer setValue:@(0.5) forKeyPath:@"transform.scale"];
// 旋转
[self.imageView.layer setValue:@(M_PI_4) forKeyPath:@"transform.rotation"];
}];
}

PS.
在这里我就不用图片了,我就劳动一下吧(图片的不好复制不是吗),福利奉上转场效果key paths

Transform field value key paths

Field Key Path Description
translation.x 设置为一个NSNumber对象的值是沿着x轴平移。
translation.y 设置为一个NSNumber对象的值沿y轴平移。
translation.z 设置为一个NSNumber对象的值沿z轴平移。
translation 设置为一个NSValue对象包含一个NSSize或CGSize数据类型。数据类型表示将在x和y轴。
scale.x 设置为一个NSNumber对象的值是x轴缩放。
scale.y 设置为一个NSNumber对象的值是y轴缩放。
scale.z 设置为一个NSNumber对象的值是z轴缩放。
scale 设置为一个NSNumber对象的值是所有三个规模因素的平均值。
rotation.x 设置为一个NSNumber对象的值是旋转,弧度,x轴。
rotation.y 设置为一个NSNumber对象的值是旋转,弧度,y轴。
rotation.z 设置为一个NSNumber对象的值是旋转,弧度,z轴。
rotation 设置为一个NSNumber对象的值是旋转,弧度,z轴。这个字段是一样设置旋转。z域。

4.CGAffineTransform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 旋转,参数指定为弧度,M_PI <-> 180
CGAffineTransformMakeRotation(CGFloat angle);
// 缩放, sx:指x轴缩放的比例,sy 在y轴上的缩放比例
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
// 平移 tx:在x轴上平移 ty 是在y上平移
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);
// 让你的view回到最原始的状态,没有缩放,没有旋转,没有平移
ballView.transform = CGAffineTransformIdentity;
// 指定在y轴上 平移
ballView.transform = CGAffineTransformMakeTranslation(0, -300);

真正的高阶技巧 iOS Core Animation

强力推荐👍《iOS Core Animation: Advanced Techniques》这本书很深入的将了Core Animation的原理性的东西,是一本讲解Core Animation原理非常深入的书,如果把整本书全部读完,理解,我相信iOS 中的
动画就是件很轻松的事情了,可惜是英文的;

在网上也找到了这本书完整的中文翻译,如果感兴趣,可以去看看 ios核心动画高级技巧

iOS Core Animation.png

最后附上这张图:
CALayer属性.png

Reading


  • 如果在阅读过程中遇到 error || new ideas,希望你能 issue 我,我会及时补充谢谢。

  • 不管谁的博客上面写的 (也包括自己),阅读的你要敢于去验证;如人饮水,冷暖自知;(共勉)。

  • 喜欢可 赞赏 or Star一波;点击左上角关注 或 微众『Codeidea』,在 Demo 更新时收到邮件通知,便捷你的阅读。

🖋 Plain boiled water ln : 本文结束    感谢阅读 ^_^. Need coffee?
👁 At this time suggest 1 minute eye exercises

本文标题:iOS 模块详解—「Core Animation 之 CALayer 图层」

文章作者:白开水ln

原始链接:http://plainboiledwaterln.cn/iOSNET/CALayer.html

版权声明: 署名-非商业性使用-禁止演绎 4.0 国际 『微众圈:Codeidea』本博客文章除特别声明外均为原创,如需转载请务必保留原链接(可点击进入的链接)和作者出处,谢谢合作!

「喜欢就留言or赞赏」but「支持不要超过你早餐费的 0.5」 ^_^.