Doz
Doz

Reputation: 7149

How do i set a CGContextRef property rather than using UIGraphicsGetCurrentContext()

Ive been trying to work with UIGraphicsGetCurrentContext and CGContextRef. I was told that using UIGraphicsGetCurrentContext() numerous times is bad and to rather work on using CGContextRef and referring to it.

I have been trying to work on the second part and I am having issues setting the @property and referring to it. Can someone give me a declaration and usage example of this? Tried googling and couldn't find any references to it.

Ta

Upvotes: 0

Views: 962

Answers (1)

rob mayoff
rob mayoff

Reputation: 386038

You probably shouldn't store the return value from UIGraphicsGetCurrentContext in a property. You usually either don't know how long the context will be valid, or the context has a short lifetime anyway. For example, if you're calling UIGraphicsGetCurrentContext from your drawRect: method, you don't know how long that context will survive after you return from drawRect:. If you're calling UIGraphicsGetCurrentContext after calling UIGraphicsBeginImageContextWithOptions, you will probably be calling UIGraphicsEndImageContext soon anyway. It would be inappropriate to keep references to those contexts around.

If you are calling many Core Graphics functions on the same context, then you want to store the context in a local variable. For example, here is a drawRect: method from one of my test projects:

- (void)drawRect:(CGRect)dirtyRect {
    NSLog(@"drawRect:%@", NSStringFromCGRect(dirtyRect));
    [self layoutColumnsIfNeeded];
    CGContextRef gc = UIGraphicsGetCurrentContext();
    CGContextSaveGState(gc); {
        // Flip the Y-axis of the context because that's what CoreText assumes.
        CGContextTranslateCTM(gc, 0, self.bounds.size.height);
        CGContextScaleCTM(gc, 1, -1);
        for (NSUInteger i = 0, l = CFArrayGetCount(_columnFrames); i < l; ++i) {
            CTFrameRef frame = CFArrayGetValueAtIndex(_columnFrames, i);
            CGPathRef path = CTFrameGetPath(frame);
            CGRect frameRect = CGPathGetBoundingBox(path);
            if (!CGRectIntersectsRect(frameRect, dirtyRect))
                continue;

            CTFrameDraw(frame, gc);
        }
    } CGContextRestoreGState(gc);
}

You can see that I'm doing a bunch of stuff with the context: I'm saving and restoring the graphics state, I'm changing the CTM, and I'm drawing some Core Text frames into it. Instead of calling UIGraphicsGetCurrentContext many times, I call it just once and save the result in a local variable named gc.

Upvotes: 4

Related Questions