[英]Creating a window graphics context for a CGLayer in iOS outside drawRect: of UIView
UIView creates a window graphics context before a custom drawRect:
method is invoked, so inside the method I can get the graphics context. UIView在调用自定义drawRect:
方法之前创建窗口图形上下文,因此在该方法内部,我可以获取图形上下文。 However, it seems that the only way to get a window graphics context in iOS, so I can make a CGLayer object based on a window graphics context only in a custom drawRect:
method of a UIView object. 但是,似乎这是在iOS中获取窗口图形上下文的唯一方法 ,因此我只能在UIView对象的自定义drawRect:
方法中基于窗口图形上下文创建CGLayer对象。
However, I might want a model object to contain a CGLayer object, which is created with the model object itself, and later a lot of views use the layer to draw its content on their own views. 但是,我可能希望模型对象包含一个CGLayer对象,该对象是由模型对象本身创建的,后来许多视图使用该图层在自己的视图上绘制其内容。 One might create a bitmap graphics context to create a CGLayer, but then everything drawn on the screen using the CGLayer object will have characteristics of a bitmap context, as Apple's documents say that drawing with a CGLayer object is restricted to the type of the graphics context used to create the layer. 人们可能会创建一个位图图形上下文来创建一个CGLayer,但是使用CGLayer对象在屏幕上绘制的所有内容都会具有位图上下文的特征,因为Apple的文档说,使用CGLayer对象进行的绘制仅限于图形上下文的类型。用于创建图层。
So my question is, is it really impossible to create a window graphics context outside drawRect:
to make a CGLayer object based on it. 所以我的问题是,是否真的不可能在drawRect:
之外创建窗口图形上下文drawRect:
基于它创建CGLayer对象。 Or, is there a better way to create and store a CGLayer object for on-screen drawing that may be shared by multiple views? 或者,是否有更好的方法为屏幕上的绘图创建和存储CGLayer对象,该对象可能由多个视图共享? Or is it a completely bogus idea to have such a shared CGLayer object outside a UIView object for a reason I don't realize? 还是出于我不知道的原因而在UIView对象之外拥有这样一个共享的CGLayer对象是完全假的想法吗?
The following examples in Swift show how I have done what the original question asks, in both iOS and OSX. Swift中的以下示例说明了如何在iOS和OSX中完成原始问题的要求。
Note: when you create a CGLayer, the graphics context that you provide is used solely as a reference to initialise the layer. 注意:创建CGLayer时,您提供的图形上下文仅用作初始化图层的参考。 No content or anything are sent to it - it just has to be the right TYPE of context so that the API knows what sort of layer to create. 没有内容或任何内容发送给它-它只必须是正确的上下文类型,以便API知道要创建哪种层。
In this example I create a CGLayer in the view controller and do some drawing on it. 在此示例中,我在视图控制器中创建一个CGLayer并在其上进行一些绘制。 Then I render it onto the screen in the drawRect() method of a view. 然后,使用视图的drawRect()方法将其渲染到屏幕上。
The view controller 视图控制器
import UIKit
class ViewController: UIViewController {
@IBOutlet var myView: MyView!
override func viewWillAppear(animated: Bool) {
// get the current graphics context - any context relevant to the screen
// will do for this purpose
let currentGraphicsContext = UIGraphicsGetCurrentContext()
// create a GCLayer with low level properties appropriate to the device
// screen and a size of 100 x 100
// this process doesn't send any content to windowGraphicsContext, it just
// copies some of the low level fields about the screen
let newLayer = CGLayerCreateWithContext(currentGraphicsContext,
CGSize(width: 100, height: 100),
nil)
// store a reference to the layer in a property of the view so that the
// view can display it
myView.layerRef = newLayer
// create a new graphics context for the layer so that we can draw on it
let myLayerContext = CGLayerGetContext(newLayer)
// draw some content on the layer
CGContextSetFillColorWithColor(myLayerContext, UIColor.redColor().CGColor)
CGContextFillRect(myLayerContext,
CGRect(x: 0, y: 0, width: 100, height: 50))
CGContextSetFillColorWithColor(myLayerContext, UIColor.blueColor().CGColor)
CGContextFillRect(myLayerContext,
CGRect(x: 0, y: 50, width: 50, height: 50))
}
}
The UIView
subclass UIView
子类
import UIKit
class MyView: UIView {
// a reference to the layer created by the view controller
var layerRef: CGLayer?
override func drawRect(rect: CGRect) {
// get a graphics context for the view
let myViewGraphicsContext = UIGraphicsGetCurrentContext()
// draw the layer into the view
CGContextDrawLayerAtPoint(myViewGraphicsContext,
CGPoint(x: 20 , y: 20),
self.layerRef)
}
}
The view controller 视图控制器
import Cocoa
class ViewController: NSViewController {
@IBOutlet var myView: MyView!
override func viewWillAppear() {
// get a graphics context for the window that contains the view - any
// context relevant to the screen will do
let windowGraphicsContext = NSGraphicsContext(window: myView.window!)
// create a GCLayer with low level properties appropriate to the device
// screen and a size of 100 x 100
// this process doesn't send any content to windowGraphicsContext, it just
// copies some of the low level fields about the screen
let newLayer = CGLayerCreateWithContext(windowGraphicsContext.CGContext,
CGSize(width: 100, height: 100), nil)
// store a reference to the layer in a property of the view, so that the
// view can display it
myView.layerRef = newLayer
// create a new graphics context for the layer so that we can draw on it
let myLayerContext = CGLayerGetContext(newLayer)
// do some drawing on the layer
CGContextSetFillColorWithColor(myLayerContext, NSColor.redColor().CGColor)
CGContextFillRect(myLayerContext,
CGRect(x: 0, y: 0, width: 100, height: 50))
CGContextSetFillColorWithColor(myLayerContext, NSColor.blueColor().CGColor)
CGContextFillRect(myLayerContext,
CGRect(x: 0, y: 50, width: 50, height: 50))
}
}
The NSView
subclass NSView
子类
import Cocoa
class MyView: NSView {
// a reference to the layer created by the view controller
var layerRef: CGLayer?
override func drawRect(dirtyRect: NSRect) {
super.drawRect(dirtyRect)
// get a graphics context for the view
let graphicsContext = NSGraphicsContext.currentContext()?.CGContext
// draw the layer into the view
CGContextDrawLayerAtPoint(graphicsContext,
CGPoint(x: 20 , y: 20),
self.layerRef)
}
}
Yes, you can create a drawing context for a CALayer from a bitmap. 是的,您可以从位图为CALayer创建图形上下文。
But the contents of a CGLayer needs a backing bitmap, since it does not save the symbolic (resolution independent) drawing vectors when drawn into, only the resulting pixels. 但是CGLayer的内容需要一个后备位图,因为在绘制时,它不保存符号(与分辨率无关)的绘制矢量,而仅保存生成的像素。 So either you create the backing bitmap, or you use the one handed you by a UIView, or you recreate/redraw the bits from your own command list when required. 因此,您可以创建支持位图,也可以使用UIView所提供的一位,也可以在需要时从自己的命令列表中重新创建/重画这些位。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.