The following is my self-defined view’s drawRect, it draw a chess board, the board has 19*19 lines, and character a-t at top and bottom sides, 1-19 at left and right sides, also 9 dots:
- (void)drawRect:(CGRect)rect
{
// Get the drawing context
CGContextRef context = UIGraphicsGetCurrentContext ();
CGContextSaveGState(context);
// Draw the board background
UIImage *bk = [UIImage imageNamed:@"board_bg_011.png"];
CGColorRef shadowColor = CreateDeviceRGBColor(0.5, 0.5, 0.5, 1);
CGContextSetShadowWithColor(context, CGSizeMake(2, 2), 10, shadowColor);
[bk drawInRect:CGRectMake(TEXT_AREA_OFFSET, TEXT_AREA_OFFSET, self.bounds.size.width - TEXT_AREA_OFFSET * 2, self.bounds.size.height - TEXT_AREA_OFFSET * 2)];
CGColorRelease(shadowColor);
CGContextRestoreGState(context);
// Draw board edage square
UIBezierPath *path = [UIBezierPath bezierPathWithRect:tableRect];
path.lineWidth = 2.0;
[path stroke];
// Draw board lines
UIBezierPath *line = [UIBezierPath bezierPath];
line.lineWidth = 1.0;
for (int i = 1; i <= 17; i ++) {
float x = tableRect.origin.x + i * qiziSize;
[line moveToPoint:CGPointMake(x, tableRect.origin.y)];
[line addLineToPoint:CGPointMake(x, tableRect.origin.y + tableRect.size.height)];
[line stroke];
float y = tableRect.origin.y + i * qiziSize;
[line moveToPoint:CGPointMake(tableRect.origin.x, y)];
[line addLineToPoint:CGPointMake(tableRect.origin.x + tableRect.size.width, y)];
[line stroke];
}
// Draw 9 dots
CGContextSaveGState(context);
CGRect dotRect = CGRectMake(0, 0, 6, 6);
CGContextTranslateCTM(context, tableRect.origin.x + qiziSize * 3 - 3, tableRect.origin.y + qiziSize * 3 - 3);
UIBezierPath *dot = [UIBezierPath bezierPathWithOvalInRect:dotRect];
[dot fill];
CGContextTranslateCTM(context, qiziSize * 6, 0);
[dot fill];
CGContextTranslateCTM(context, qiziSize * 6, 0);
[dot fill];
CGContextTranslateCTM(context, - qiziSize * 12, qiziSize * 6);
[dot fill];
CGContextTranslateCTM(context, qiziSize * 6, 0);
[dot fill];
CGContextTranslateCTM(context, qiziSize * 6, 0);
[dot fill];
CGContextTranslateCTM(context, - qiziSize * 12, qiziSize * 6);
[dot fill];
CGContextTranslateCTM(context, qiziSize * 6, 0);
[dot fill];
CGContextTranslateCTM(context, qiziSize * 6, 0);
[dot fill];
CGContextRestoreGState(context);
CGContextSaveGState(context);
UIFont *font = [UIFont fontWithName:@"Helvetica" size:12];
int fontHeight = [@"1" sizeWithFont:font].height;
UIColor *textColor = [UIColor grayColor];
[textColor setFill];
[textColor setStroke];
for (int i = 1; i <= 19; i ++) {
// Top text
NSString *str = [NSString stringWithFormat:@"%c", ((i < 9)?i:(i+1)) + 'A' - 1];
CGRect textRect = CGRectMake(tableRect.origin.x + qiziSize * (i - 1) - qiziSize / 2, 0, qiziSize, TEXT_AREA_OFFSET);
[str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];
// Bottom text
textRect.origin.y = self.bounds.size.height - TEXT_AREA_OFFSET + 2;
[str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter];
// Left text
str = [NSString stringWithFormat:@"%i", i];
textRect = CGRectMake(0, tableRect.origin.y + qiziSize * (i - 1) - fontHeight / 2, TEXT_AREA_OFFSET - 2, fontHeight);
[str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentRight];
// Right text
textRect.origin.x = self.bounds.size.width - TEXT_AREA_OFFSET + 2;
[str drawInRect:textRect withFont:font lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentLeft];
}
CGContextRestoreGState(context);
}
Running on iPad3, this method takes more than 1 second. Is there any suggestion on how to optimize it?
Thanks in advance.
I assume this follows on from your earlier question about poor rotation performance.
Creating and drawing (and scaling) images and fonts is expensive. Using the time profiler in instruments will highlight the most expensive areas of your code, but those are the most likely candidates.
You should consider decomposing your view into UIImageView and UILabel instances, which will cache their backing stores and not need to be redrawn, just repositioned. However, you shouldn’t do anything until you’ve profiled your code and found the performance bottlenecks.