iOS 高级核心动画 day01 – 图层树、UIView、CALayer

时间:2021-7-9 作者:qvyue

一、图层树(认识 UIView 和 CALayer)

1. iOS 中所有的视图都从哪个视图派生而来?

  • iOS 中,所有的视图都从一个叫做 UIView的基类派生而来

2. UIView 可以做些什么事情(至少说三点)?

  • UIView 可以处理触摸事件。
  • UIView 可以基于 Core Graphics 绘图。
  • UIView 可以做简单动画,类似滑动、渐变、旋转、缩放。

3. CALayer 和 UIView 的异同点(至少各说一个)?

  • 同:CALayer 和 UIView 都是被层级关系树管理的矩形框,同样也可以包含一些内容(像图片、文本或背景色)
  • 异:CALayer 和 UIView 最大的不同是 不处理用户的交互

4. 为什么不用一个简单层级来处理所有事情,而且提供 UIView 和 CALayer 呢?

  • 主要为了职责分离,这样也能避免很多重复代码。
  • 比如在 iOS 平台,由 UIView 处理用户手指触摸事件,在 Mac OS 平台由 NSView 处理用户 鼠标键盘事件,但是可以共用 CALayer。
  • 这也就是为什么iOS有UIKit和UIView,但是Mac OS有AppKit和NSView的原因

二、寄宿图(layer.contents)

1. layer.contents 是干啥的?如何用单纯的一个 UIView 展示一张图片?

  • CALayer 有个一个属性叫做 contents,这个属性使用来展示 CGImage 的。
  • layer.contents 也就是寄宿图
  • 使用 UIView 的 layer 展示 image.CGImage 方法如下:
UIImage *snowImage = [UIImage imageNamed:@"snow.png"];
self.layerView.layer.contents = (__bridge id _Nullable)(snowImage.CGImage);

2. 给 contents 赋值 CGImage 的值是唯一设置寄宿图的方法吗?

  • 不是唯一方法。
  • 还可以通过继承 UIView 并且实现 -drawRect: 方法来自定义绘制。

3. 为什么如果不需要寄宿图,就不要创建 -drwaRect 方法?

  • 因为对于 UIView 来说,寄宿图并不是必须的,它并不在意那到底是单调的颜色还是有一个图片的实例。
  • 如果 UIView 检测到 -drawRect: 方法被调用了,系统就会为视图分配一个寄宿图,这个寄宿图的像素尺寸等于视图大小乘以 contentsScale 的值。
  • 如果你不需要寄宿图,那就不要创建这个方法了,这会造成CPU资源和内存的浪费,这也是为什么苹果建议:如果没有自定义绘制的任务就不要在子类中写一个空的-drawRect:方法。

4. layer.contentsScale 是干啥的?

  • contentsScale属性定义了寄宿图的像素尺寸和视图大小的比例,默认情况下它是一个值为1.0的浮点数。
  • 如果contentsScale设置为1.0,将会以每个点1个像素绘制图片,如果设置为2.0,则会以每个点2个像素绘制图片,这就是我们熟知的Retina屏幕。

5. iOS视图绘制有哪三种坐标系统?

  • — 在 iOS 和 MacOS 中最常见的坐标系。点就像是虚拟的像素,也被称为逻辑像素。在标准设备上,一个点就是一个像素,但是在 Retina 设备上,一个点等于 2*2 个像素。iOS 用点作为屏幕的坐标测算体系就是为了在 Retina 设备和普通设备上能有一致的视觉效果
  • 像素 — 物理像素坐标并不会用来屏幕布局,但是仍然与图片有相对关系。UIImage 是一个屏幕分辨率解决方案,所以指定点来度量大小。但是一些底层图片表示如 CGImage 就会使用像素,所以你要清除在 Retina 设备和普通设备上,他们表现出来不同的大小。
  • 单位 — 对于与图片大小或是图层边界相关的显示,单位坐标是一个方便的度量方式,当大小改变的时候,也不需要再次调整。单位坐标在 OpenGL 这种纹理坐标系中用得很多,Core Animation 中也用到了单位坐标。

6. layer.contentsRect 是哪种坐标系?

  • 默认的 contentsRect 是 {0,0,1,1},是单位坐标系。这意味着整个寄宿图默认都是可见的,如果我们制定一个小一点的矩形,图片就会被裁剪,如下图
iOS 高级核心动画 day01 - 图层树、UIView、CALayer
image.png

7. layer.contentsRect 可以实现雪碧图image sprites(图片拼合)的效果吗?

  • 可以。

8. layer.contentsCenter 有什么作用?

  • 看名字你可能以为它可能跟图片的位置有关,不过这个名字着实误导了你。
  • contentsCenter 其实是一个 CGRect,它定义了一个固定的边框和一个在图层上可拉伸的区域。
  • 他工作起来的效果和UIImage里的-resizableImageWithCapInsets: 方法效果非常类似
iOS 高级核心动画 day01 - 图层树、UIView、CALayer
image.png

参考文章 https://www.kancloud.cn/manual/ios/97770

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。