如何优化drawRect?

时间:2012-10-07 14:42:15

标签: ios ipad drawrect

以下是我自定义视图的drawRect,它画一个棋盘,棋盘有19 * 19行,顶部和底部有字符,左右两边有1-19,还有9个点:< / p>

- (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);
}

在iPad3上运行,此方法需要1秒钟以上。有没有关于如何优化它的建议?

提前致谢。

1 个答案:

答案 0 :(得分:2)

我认为这是因为你之前关于旋转性能不佳的问题。

创建和绘制(和缩放)图像和字体非常昂贵。在仪器中使用时间分析器将突出显示代码中最昂贵的区域,但这些区域最有可能成为候选者。

您应该考虑将视图分解为UIImageView和UILabel实例,这些实例将缓存其后备存储,而不需要重新绘制,只需重新定位。但是,在分析代码并发现性能瓶颈之前,不应该执行任何