Optimize CGContextDrawRadialGradient in drawRect:
Asked Answered
C

1

4

In my iPad app, I have a UITableView that alloc/inits a UIView subclass every time a new cell is selected. I've overridden drawRect: in this UIView to draw a radial gradient and it works fine, but performance is suffering - when a cell is tapped, the UIView takes substantially longer to draw a gradient programmatically as opposed to using a .png for the background. Is there any way to "cache" my drawRect: method or the gradient it generates to improve performance? I'd rather use drawRect: instead of a .png. My method looks like this:

- (void)drawRect:(CGRect)rect
{
     CGContextRef context = UIGraphicsGetCurrentContext();

     size_t gradLocationsNum = 2;
     CGFloat gradLocations[2] = {0.0f, 1.0f};
     CGFloat gradColors[8] = {0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.5f}; 
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
     CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradColors, gradLocations, gradLocationsNum);
     CGColorSpaceRelease(colorSpace);

     CGPoint gradCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
     float gradRadius = MIN(self.bounds.size.width , self.bounds.size.height) ;

     CGContextDrawRadialGradient (context, gradient, gradCenter, 0, gradCenter, gradRadius, kCGGradientDrawsAfterEndLocation);

     CGGradientRelease(gradient);
}

Thanks!

Carrol answered 10/7, 2012 at 20:15 Comment(0)
M
2

You can render graphics into a context and then store that as a UIImage. This answer should get you started:

drawRect: is a method on UIView used to draw the view itself, not to pre-create graphic objects.

Since it seems that you want to create shapes to store them and draw later, it appears reasonable to create the shapes as UIImage and draw them using UIImageView. UIImage can be stored directly in an NSArray.

To create the images, do the following (on the main queue; not in drawRect:):

1) create a bitmap context

UIGraphicsBeginImageContextWithOptions(size, opaque, scale);

2) get the context

CGContextRef context = UIGraphicsGetCurrentContext();

3) draw whatever you need

4) export the context into an image

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

5) destroy the context

UIGraphicsEndImageContext();

6) store the reference to the image

[yourArray addObject:image];

Repeat for each shape you want to create.

For details see the documentation for the above mentioned functions. To get a better understanding of the difference between drawing in drawRect: and in arbitrary place in your program and of working with contexts in general, I would recommend you read the Quartz2D Programming Guide, especially the section on Graphics Contexts.

Mok answered 16/11, 2012 at 20:56 Comment(2)
There’s no highlighting hint for Objective-C, as far as I can tell. Will plain C work?Mok
I have seen the error of my ways, and will repent :) (thanks for the edit)Mok

© 2022 - 2024 — McMap. All rights reserved.