繁体   English   中英

在UIView的drawRect外部为iOS中的CGLayer创建窗口图形上下文

[英]Creating a window graphics context for a CGLayer in iOS outside drawRect: of UIView

UIView在调用自定义drawRect:方法之前创建窗口图形上下文,因此在该方法内部,我可以获取图形上下文。 但是,似乎这在iOS中获取窗口图形上下文的唯一方法 ,因此我只能在UIView对象的自定义drawRect:方法中基于窗口图形上下文创建CGLayer对象。

但是,我可能希望模型对象包含一个CGLayer对象,该对象是由模型对象本身创建的,后来许多视图使用该图层在自己的视图上绘制其内容。 人们可能会创建一个位图图形上下文来创建一个CGLayer,但是使用CGLayer对象在屏幕上绘制的所有内容都会具有位图上下文的特征,因为Apple的文档说,使用CGLayer对象进行的绘制仅限于图形上下文的类型。用于创建图层。

所以我的问题是,是否真的不可能在drawRect:之外创建窗口图形上下文drawRect:基于它创建CGLayer对象。 或者,是否有更好的方法为屏幕上的绘图创建和存储CGLayer对象,该对象可能由多个视图共享? 还是出于我不知道的原因而在UIView对象之外拥有这样一个共享的CGLayer对象是完全假的想法吗?

Swift中的以下示例说明了如何在iOS和OSX中完成原始问题的要求。

注意:创建CGLayer时,您提供的图形上下文仅用作初始化图层的参考。 没有内容或任何内容发送给它-它只必须是正确的上下文类型,以便API知道要创建哪种层。

在此示例中,我在视图控制器中创建一个CGLayer并在其上进行一些绘制。 然后,使用视图的drawRect()方法将其渲染到屏幕上。


iOS示例

视图控制器

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))
    }
}

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)
    }
}

OSX范例

视图控制器

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))
    }
}

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)
    }
}

是的,您可以从位图为CALayer创建图形上下文。

但是CGLayer的内容需要一个后备位图,因为在绘制时,它不保存符号(与分辨率无关)的绘制矢量,而仅保存生成的像素。 因此,您可以创建支持位图,也可以使用UIView所提供的一位,也可以在需要时从自己的命令列表中重新创建/重画这些位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM