簡體   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