0

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.

TieDad
  • 9,143
  • 5
  • 32
  • 58

1 Answers1

2

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.

jrturton
  • 118,105
  • 32
  • 252
  • 268
  • With the instrument tool, I found that [UIImage drawInRect] eats most of CPU time. That is to draw background of the chess board, I use a big png file. With trying to comment out the drawingInRect, performance increase significantly. Thanks. – TieDad Oct 08 '12 at 07:17