在Apple的核心动画文档中,它说有两个渲染路径。据我所知,CALayer缓存UIView
内容的位图数据。有两种方法可以提供CALayer的内容。一个是实现drawRect:
或其他CALayer绘图方法,另一个是将位图设置为CALayer的属性内容。
我想知道,如果以上两件事都没有完成,幕后会发生什么?我相信在这种情况下有一个私人绘图路径UIView
。这个私人绘图路径是由什么组成的?它是如何工作的?
答案 0 :(得分:0)
有三种方法可以为图层提供内容。
- Assign an image object directly to the layer object’s contents property.
- Assign a delegate object to the layer and let the delegate draw the layer’s content.
- Define a layer subclass and override one of its drawing methods to provide the layer contents yourself.
如果我们没有实现drawRect:
或设置contents
属性或子类的图层,它将使用默认方式,即第二个向Layer支持的视图层提供内容。该图层将捕获视图的内容并进行渲染。
答案 1 :(得分:0)
CALayer不使用drawRect绘制任何内容:只有基于视图的绘图技术(如Core Graphics)才使用drawRect:但这种方式的唯一问题是它是在CPU和主线程上完成的,这使得它成为一个昂贵的过程。因此,Core Animation直接在图形硬件中操作应用程序内容的缓存位图,这是更加优化的。您可以通过其中一个委托(displayLayer:或drawLayer:inContext)或使用您提到的contents属性更新或提供Core Animation层的初始内容。 Core Animation中的所有图层对象都来自CALayer。
CALayer只是一个属于Core Animation的图层对象,它本身就是UIView的支持系统或UIView的子类。 Core Animation不是一种绘图技术,因为它无法创建原始形状,如Quartz,Open GL ES和Metal can。相反,Core Animation允许您操作现有视图,它通过缓存UIView的位图数据并将其发送到要操作的图形硬件来完成此操作。我们说Core Animation是一个支持系统,它的所有工作都依赖于使用CALayer为主要类型的图层对象。当然,如果视图具有图层并且视图实际上不需要存在图层,则它只能执行此操作。但是,在iOS中,所有视图都默认附加了一个图层。我们说iOS中的视图是"层支持"。在MacOS中,您需要实际为视图添加Core Animation支持。
CALayer内容的实际绘制有几个方面。第一个是改变你提到的CALayer的contents属性,你通过给它一个CGImageRef来做到这一点。第二种方法是在子类中实现或覆盖CALayer委托displayLayer:它创建一个位图并将其设置为图层的content属性。第三种方法是在子类中实现或覆盖CALayer委托drawLayer:inContext,它创建一个位图,创建一个绘制到该位图的图形上下文,然后调用你的委托方法来填充位图。
在iOS中,我们通常不担心如何呈现视图图层的内容。由于所有视图都是图层支持的,因此iOS使用我刚刚描述的方法管理如何以最有效的方式呈现这些视图。这是一种优化,可以节省您的时间,并且使图层非常易于使用。如果您正在为MacOS开发视图并非始终是图层支持的,那么您通常会担心会覆盖这些代理或者对它们进行子类化。如果您决定不在iOS中使用默认的CALayer,您可能也会担心这一点,例如,您可能会将视图的图层从CALayer更改为CAMetalLayer。或者,如果您正在寻找性能优化,甚至可以在少数情况下进行。
答案 2 :(得分:0)
CALayer的关键在于它支持GPU。在现代图形和动画中,您希望最小化位图数据在CPU和GPU之间穿越的次数。这些操作成本很高。
CALayer 始终使用私人绘图路径,无论您使用setContents:
还是drawRect:
。事实上,CALayer的底层管道以基本相同的方式处理这两者。当您setContents:
时,CALayer会获取您提供的图像,并通过OpenGL(可能是现在的Metal)调用将其上传到GPU。当drawRect:
CALayer为您提供可以绘制的上下文时,它会对位图数据执行相同的操作。
如果你没有设置内容或实现drawRect,你仍然可以做一些事情,比如设置图层的背景颜色,边框,角半径等。这是由CALayer基于GPU的私人绘图路径渲染的。