42

我一直使用 CoreGraphics 和 CoreAnimation,我了解它们各自是如何独立工作的,但不是那些必须与对方交谈的边缘情况。我也知道UIViews 是一个很好的包装器,渲染的繁重工作CALayer在哪里,并且增加了基于触摸的响应能力。CALayerUIView

但是,到目前为止,我看到的所有问题都是从一侧或另一侧解决问题,而不是它们之间的相互作用,特别是 CoreGraphics 和CALayer.

无论如何,我的问题是...

CoreGraphics 与 CALayer 有什么关系?

我的理解是,aCALayer包装了 CoreGraphics 方法来绘制自己,但只绘制一次,并且可以使用自身的快照直到失效。但是,这些绘图方法如何与该层的子层相互作用?他们是独家的吗?

例如,当我有一个UIView具有子视图的子视图并且我重载该drawRect方法时会发生什么?这如何影响其子层的绘制?

将两者混合在同一个函数中甚至是一个好主意吗?

另外,我只问 iOS,我知道 Mac 是一个不同的野兽(也有那些花哨CIFilters的混蛋!)。

先前的研究

以下是我事先研究过的一些相关问题:

  1. 关于quartz2d、核心图形、核心动画、核心图像的混淆。这个问题询问彼此之间的差异,并且选择的答案确实提供了,但它为每个单独的库回答,就好像另一个库不存在一样。
  2. Drawrect 或不 Drawrect。另一个很好的问题,但它只解决了绘制 CoreGraphics 与将问题交给 UIKit 的主题,但无论如何,选择的答案提供了部分难题。
  3. 使用自定义 CALayer 动画饼片。一定是我在这个主题中看到的最有价值的教程之一,它是唯一一个指导我绘制 CALayer 的教程
  4. CoreGraphics 和 CoreAnimation 有什么不同对提问者接受答案的速度感到非常失望,我觉得这里还有更多内容。
  5. 各种 WWDC 视频,但我还没有看到详细解释一般范围的视频。如果有人回复了 WWDC 视频,我会认为这是一个有效的答案。
4

1 回答 1

40

我将尝试在 20,000 英尺的概念层面回答您的问题。我将尝试否认我过度概括的观点,但我会尝试解决常见问题。

考虑它的最简单方法可能是:在 GPU 的内存中,您有纹理,出于本次讨论的目的,这些纹理是位图图像。CALayer 可能有与之关联的纹理,也可能没有。这些情况将分别对应于具有-drawRect:方法的层和仅存在以包含子层的层。从概念上讲,每个具有与之关联的纹理的层都有自己的不同纹理(有一些细节和优化使得这不是严格/普遍正确的,但在一般的抽象情况下,它可以帮助考虑这个方式。)考虑到这一点,超层的方法-drawRect:对其任何子层的方法都没有影响-drawRect:,并且(再次,在一般情况下)子层的-drawRect:方法对其超层没有影响'-drawRect:方法。每个都绘制到自己的纹理(也称为“后备存储”)中,然后基于层树和相关的几何图形和变换,GPU 将所有这些纹理组合在一起,形成您在屏幕上看到的内容。当其中一个图层直接或间接(通过-setNeedsDisplayInRect:)无效时,当 CA 开始在屏幕上显示下一帧时,将通过-drawRect:调用它们的方法来重绘无效图层。这将更新关联的纹理,一旦所有无效图层的纹理都更新,GPU 将合成它们,生成您在屏幕上看到的最终位图。

-drawRect:所以回答你的第一个问题:在一般情况下,不,不同 CALayers的方法之间没有相互作用。

至于您的第二个问题:出于本次讨论的目的,您可以将 UIViews 视为与 CALayers 相同。与非 UIView CALayers 相比,绘图和纹理的相互关系在很大程度上没有变化。

对于您的第三个问题:混合 UIViews 和 CALayers 是个好主意吗?每个 UIView 都有一个 CALayer 支持它(UIKit 中的所有视图都是层支持的,这在 OSX 上通常不是这种情况。)所以在某种程度上,无论你是否希望它们是“混合的”。将 CALayer 子层添加到支持 UIView 的层是非常好的,尽管该层不会具有 UIView 为聚会带来的所有附加功能。如果该层的目的只是生成用于显示的图像,那很好。如果您希望子层/视图成为触摸处理的一流参与者,或者使用 AutoLayout 定位/调整大小,那么它需要是 UIView。最好将 UIView 视为一个 CALayer,并添加了一堆额外的功能。如果您需要该功能,请使用 UIView。

总之:CoreGraphics 是一个用于绘制 2D 图形的 API。CG 的一种常见用途(但不是唯一用途)是绘制位图图像。CoreAnimation 是一个 API,它为在屏幕上操作位图提供了一个有组织的框架。您可以有意义地使用 CoreAnimation 而无需调用 CoreGraphics 绘图原语,例如,如果您的所有纹理都由在构建时编译到您的应用程序中的图像支持。

希望这会有所帮助。如果您需要澄清,请发表评论,我将进行编辑以提供帮助。

于 2013-07-20T12:31:33.293 回答