mangerlahn
mangerlahn

Reputation: 4966

Draw NSString into CALayer

I have to draw a NSString into a CALayer object for animation reasons. This is why I can't use CATextLayer.

The problem is that I am not able to get the text visible on screen. I know that I have to draw inside the graphicsContext, that is handed over within drawInContext(). I can't figure out how to create the NSGraphicsContext instance out of the CGContext instance. The graphicsContextWithGraphicsPort class method is deprecated. Is there any replacement for it?

Note: I am using Swift.

Upvotes: 2

Views: 1227

Answers (1)

Hamish
Hamish

Reputation: 80801

You can now use the init(CGContext graphicsPort: CGContext, flipped initialFlippedState: Bool) initialiser.

So, for example, if you're subclassing CALayer and overriding the drawInContext() function, your code will look something like this:

override func drawInContext(ctx: CGContext) {

    NSGraphicsContext.saveGraphicsState() // save current context

    let nsctx = NSGraphicsContext(CGContext: ctx, flipped: false) // create NSGraphicsContext
    NSGraphicsContext.setCurrentContext(nsctx) // set current context

    NSColor.whiteColor().setFill() // white background color
    CGContextFillRect(ctx, bounds) // fill

    let text:NSString = "Foo bar" // your text to draw

    let paragraphStyle = NSMutableParagraphStyle() // your paragraph styling
    paragraphStyle.alignment = .Center

    let textAttributes = [NSParagraphStyleAttributeName:paragraphStyle.copy(), NSFontAttributeName:NSFont.systemFontOfSize(50), NSForegroundColorAttributeName:NSColor.redColor()] // your text attributes

    let textHeight = text.sizeWithAttributes(textAttributes).height // height of the text to render, with the attributes
    let renderRect = CGRect(x:0, y:(frame.size.height-textHeight)*0.5, width:frame.size.width, height:textHeight) // rect to draw the text in (centers it vertically)

    text.drawInRect(renderRect, withAttributes: textAttributes) // draw text

    NSGraphicsContext.restoreGraphicsState() // restore current context
}

The delegate implementation would be identical.

Upvotes: 5

Related Questions