CALayer&的drawRect

时间:2013-04-12 08:10:39

标签: ios uiview calayer

View and Window Architecture中声明,引用:

视图与核心动画层结合使用,以处理视图内容的渲染和动画。 UIKit 中的每个视图都由图层对象(通常是CALayer类的一个实例)支持,该图层管理视图的后备存储并处理与视图相关的动画。

在“视图绘制周期”部分中进一步阐述:

UIView类使用按需绘图模型来呈现内容。当视图首次出现在屏幕上时,系统会要求其绘制其内容。 系统会捕获此内容的快照,并将该快照用作视图的可视化表示。

这是否意味着,在其drawRect方法调用中的视图中绘制的内容是在保存在其后备核心动画层中的快照中捕获的?

如果没有,这个内容快照“驻留”在哪里?

如果没有,这是否意味着CALayer用于呈现“静态”内容,内容不会经常变化,而drawRect用于呈现经常变化的内容,例如在游戏应用中?

P.S。

这些问题与任何特定的代码实现无关。

我只是想了解ios视图层架构。

3 个答案:

答案 0 :(得分:10)

  

这是否意味着,在其drawRect方法调用中的视图中绘制的内容是在保存在其后备核心动画层中的快照中捕获的?

是。一切都使用引擎盖下的层。 UIView的-drawRect将捕获您绘制的内容,并且(据我所知)在视图的子图层上设置content。它甚至可能在主层对象上执行此操作。这就是'快照'被保存的地方。

  

如果没有,这是否意味着CALayer用于呈现“静态”内容,   不经常更改的内容,drawRect用于呈现   经常变化的内容,例如在游戏应用中?

内容更改的频率并不会影响选择。使用drawRect与手动创建CALayer没有太大区别。这取决于您希望如何组织视图中的子元素,或者是否要创建低级可重用图层对象而没有UIView的详细信息(例如CATextLayer)。如果要绘制各种不同的子元素,则可以使用自己的自定义绘图代码将它们拆分为不同的图层。如果您只需要绘制一个简单的内容,则可以在单个drawRect实现中完成所有操作。

说完这些之后,你需要知道每一层最终都会成为一个独立的GPU“元素”,因此减少你拥有的图层数量或使用shouldRasterize可以带来性能上的好处。父图层的+ rasterizationScale属性。这将拍摄整个图层层次结构的快照,并创建一个要渲染的光栅化图像,而不是n个单独的图像。

答案 1 :(得分:1)

  

这是否意味着,在其drawRect方法调用中的视图中绘制的内容是在保存在其后备核心动画层中的快照中捕获的?

两个字:“实施细节”

  

如果没有,这是否意味着CALayer用于呈现“静态”内容,内容不会经常变化,而drawRect用于呈现经常变化的内容,例如在游戏应用中?

不完全是。图层非常擅长动画内容(如框架名称Core Animation 所示)。 drawRect适用于高级绘图,但可以减慢每帧重绘(显然取决于你的绘图)。

我的问题中没有提及the Core Animation Programming Guide。这是了解有关视图层部分的更多信息的好地方。

答案 2 :(得分:0)

每个UIView都有一个底层CALayer(它实际上是在屏幕上呈现的)。

CALayer只是一个位图(保持像素)。当您将setNeedsDisplay调用到视图时,CALayer会被标记为重绘。在运行循环结束时,处理事件后,将创建CGContextRef并调用drawRect委托。然后,您可以将事物绘制到创建的上下文中,然后将其复制到位图中,并最终与其他图层合成以显示在屏幕上。

是的,“快照”存储在CALayer中。这只是一个优化,因此除非标记为重绘(使用setNeedsDisplay),否则图层不必重绘自己。