如何从UIView创建一个CGLayer用于离屏绘图

McK*_*ssy 5 iphone quartz-2d ipad ios

我已经阅读了我认为是Quartz 2D Programming Guide的相关部分,但无法找到以下答案(他们似乎没有在文档中谈论iOS):

我的应用程序在a中显示绘图UIView.我不得不以某种方式更新绘图,例如更改其中一个形状的填充颜色(我保留CGPathRefs重要的形状,以便以后可以用不同的填充颜色重绘它们).如上述文档第169页的"使用CGLayer绘图"一节中所述,我正在考虑将整个绘图绘制成CGContext我将从中获取的绘图CGLayer,如下所示:

CGContextRef offscreenContext = CGLayerGetContext(offscreenLayer);
Run Code Online (Sandbox Code Playgroud)

然后我可以在屏幕上更新屏幕CGContextCGLayerUIViewdrawRect:方法中绘制到我的UIView中,如下所示:

CGContextDrawLayerAtPoint(viewContext, CGPointZero, offscreenLayer);
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,我CGLayer从哪里得到我的?我的理解是我必须使用它CGLayerCreateWithContext并提供CGContext一个参数,从中继承它的大部分属性.显然,正确的背景将是UIView我所接受的背景

CGContextRef viewContext = UIGraphicsGetCurrentContext();
Run Code Online (Sandbox Code Playgroud)

但是如果我没有弄错的话,我只能在drawRect:方法中得到它,并且假设下次调用该方法时我给出的上下文将是相同的一个是无效的,即我只能在CGContext本地使用它方法.

那么,我怎样才能得到一个CGContext我可以用来初始化我CGLayer创建一个屏幕CGContext来绘制然后将整个图层绘制回我UIViewCGContext

PS:当你在它的时候; 如果上面的任何内容没有意义或没有理智,请告诉我.我刚刚开始关注Quartz 2D.

Rpr*_*ata 1

首先,如果您是在 iOS 环境中执行此操作,我认为您是对的。该文档明确指出,获得 a 的唯一方法CGContextRef

CGContextRef ctx = UIGraphicGetCurrentContext();
Run Code Online (Sandbox Code Playgroud)

然后您使用该上下文来创建CGLayerwith

CGLayerRef layer = CGLayerCreateWithContext(ctx, (CGSize){0,0}, NULL);
Run Code Online (Sandbox Code Playgroud)

如果您想在该图层上绘制,则必须使用从该图层获得的上下文来绘制它。(它与您之前创建 CGLayer 时传入的上下文有些不同)。我猜它CGLayerCreateWithContext会保存从传入的上下文中获取的信息,但不是所有信息。(示例之一是 ColorSpace 信息,当您使用来自 的上下文填充某些内容时,必须重新指定CGLayer)。

您可以从该函数获取 CGLayer 上下文引用CGLayerGetContext()并使用它来绘制。

CGContextRef layerCtx = CGLayerGetContext(layer);
CGContextBeginPath(layerCtx);
CGContextMoveToPoint(layerCtx, -10, 10);
CGContextAddLineToPoint(layerCtx, 100, 10);
CGContextAddLineToPoint(layerCtx, 100, 100);
CGContextClosePath(layerCtx);
Run Code Online (Sandbox Code Playgroud)

我发现的一点是,当您在屏幕外绘制某些内容时,它会自动将其剪辑到屏幕外。(有道理,所以它不会绘制看不见的东西)但是当您移动图层时(使用矩阵变换)。剪切路径未显示(丢失)。

最后一件事,如果将对图层的引用保存到变量中,然后想要绘制它,则可以使用CGContextDrawLayerAtPoint()类似的方法

CGContextDrawLayerAtPoint(ctx, (CGPoint) {newPointX, newPointY}, layer);
Run Code Online (Sandbox Code Playgroud)

它将在该 newPointX 和新 PointY 坐标处“标记”或“绘制”图层。

我希望能回答您的问题,如果没有请告诉我。