我总是使用CoreGraphics和CoreAnimation,我理解他们每个人如何独立工作,而不是那些必须与另一个人交谈的边缘情况。我也理解UIView
是CALayer
的一个不错的包装器,其中CALayer
完成渲染的所有繁重工作,UIView
添加了基于触摸的响应。< / p>
但是,到目前为止我所看到的所有问题都是从一方或另一方面解决问题,而不是它们之间的相互作用,特别是在CoreGraphics和CALayer
之间。
无论如何,我的问题是......
我的理解是CALayer
包装了CoreGraphics方法来绘制自己,但只执行一次,并且可以使用自身的快照直到失效。但是,这些绘图方法如何与该层的子图层相互作用?它们是独家的吗?
例如,如果我的UIView
有子视图,并且我重载了drawRect
方法,会发生什么?这对它的子图层的绘制有何影响?
将两者混合在同一个函数中是不是一个好主意?
另外,我只询问iOS ,我知道Mac是一个不同的野兽(也有那些花哨的CIFilters
,混蛋!)。
以下是我事先研究过的一些相关问题:
答案 0 :(得分:40)
我会尝试以20,000英尺的概念回答你的问题。我会试图否定我过分概括的观点,但我会试图解决这个常见问题。
考虑它的最简单的方法可能就是:在GPU的内存中,你有纹理,为了讨论的目的,这些纹理是位图图像。 CALayer可能具有与之关联的纹理,或者可能没有。这些情况分别对应于具有-drawRect:
方法的层和仅包含子层的层。从概念上讲,每个具有与之关联的纹理的图层都具有不同的纹理(有一些细节和优化使得这不是严格/普遍正确的,但在一般的抽象情况下,它可以帮助将其想象一下方式。)考虑到这一点,超级层的-drawRect:
方法对其任何子层的-drawRect:
方法没有影响,并且(在一般情况下)子层的-drawRect:
方法具有对其超级层的-drawRect:
方法没有影响。每个都绘制自己的纹理(也称为“后备存储”),然后,基于图层树和相关的几何和变换,GPU将所有这些纹理组合成您在屏幕上看到的内容。当其中一个图层直接或间接无效(通过-setNeedsDisplayInRect:
)时,当CA开始在屏幕上显示下一帧时,将通过调用其-drawRect:
方法重绘无效图层。这将更新相关的纹理,一旦更新了所有无效图层的纹理,GPU将合成它们,生成您在屏幕上看到的最终位图。
所以回答你的第一个问题:在一般情况下,不,不同CALayers的-drawRect:
方法之间没有相互作用。
关于你的第二个问题:为了讨论的目的,你可以认为UIViews和CALayers一样。与绘图和纹理相关的相互关系与非UIView CALayers的相互关系基本没有变化。
提出第三个问题:混合使用UIViews和CALayers是个好主意吗?每个UIView都有一个CALayer支持它(UIKit中的所有视图都是由层支持的,在OSX上通常不是这种情况。)因此,在某种程度上,它们是“混合”的,无论你是否想要它们。将CALayer子图层添加到支持UIView的图层是完全可以的,尽管该图层不会具有UIView为聚会带来的所有附加功能。如果该图层的目的只是为了生成图像以供显示,那就没问题。如果您希望子图层/视图成为触摸处理的第一类参与者,或者使用AutoLayout定位/调整大小,那么它将需要是UIView。最好将UIView视为CALayer,并添加一些额外的功能。如果您需要该功能,请使用UIView。如果不这样做,请使用CALayer。
总之:CoreGraphics是一个用于绘制2D图形的API。 CG(但不是唯一的)的一个常见用途是绘制位图图像。 CoreAnimation是一个API,提供了一个有组织的框架,用于在屏幕上操作位图。你可以在没有调用CoreGraphics绘图原语的情况下有意义地使用CoreAnimation,例如,如果所有纹理都由在构建时编译到应用程序中的图像支持。
希望这很有帮助。如果您需要澄清,请留下评论,我将编辑以强制执行。