CATiledLayer,CGContextDrawImage和CGContextTranslateCTM

时间:2012-01-08 14:11:01

标签: iphone objective-c quartz-graphics quartz-2d

我有一个很大的UIScrollView,其中包含一个CATiledLayer,我用它来绘制drawRect:中大得多的瓷砖,如下所示:

- (void)drawRect:(CGRect)rect {
    int firstCol = floorf(CGRectGetMinX(rect) / tileSize);
    int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize);
    int firstRow = floorf(CGRectGetMinY(rect) / tileSize);
    int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, 0, tileSize);
CGContextScaleCTM(context, 1.0, -1.0);

    for( int row = firstRow; row <= lastRow; row++ ) {
    for( int col = firstCol; col <= lastCol; col++ ) {
            UIImage = [self getTileWithRow:row column:col];

            CGRect tileRect = CGRectMake((col * tileSize), 
                                         row * tileSize),
                                         tileSize, tileSize);

            CGContextTranslateCTM(context, 0, tileRect.size.height);
            CGContextScaleCTM(context, 1.0, -1.0);
            CGContextDrawImage(context, tileRect, tile.CGImage);
        }
    }

    CGContextRestoreGState(context);
}

当我发表CGContextSaveGStateCGContextSaveGStateCGContextScaleCTMCGContextRestoreGState来电时,这种情况有效,但图片却是颠倒的。在呼叫到位时,根本不绘制图像。我可以使用[tile drawInRect:],但是反向绘制行,这会使较大的图像搞砸。

我在翻译时做错了什么?

编辑:移动保存/恢复并按照建议转换出循环,但它仍然没有绘制任何内容。

2 个答案:

答案 0 :(得分:4)

设置正确的转换以垂直翻转内容是非常困难的。没有看到任何东西的可能原因是因为转换将图像移动到rect之外。我以前做过,但不记得我是怎么做的。现在我在CATiledLayer上设置“geometryFlipped = YES”,这对我来说是翻转。

顺便说一句,为什么不将CATiledLayer的“tileSize”设置为tile的大小,那么你不需要这个for-loop tile映射的东西。每个瓷砖都会调用一次drawRect,因此您可以简单地执行:

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

    int col = floorf(CGRectGetMinX(rect) / tileSize);
    int row = floorf(CGRectGetMinY(rect) / tileSize);

    UIImage tile = [self getTileWithRow:row column:col];

    CGContextDrawImage(context, rect, tile.CGImage);
}

答案 1 :(得分:2)

首先,将所有CGContextSaveGState / CGContextRestoreGState移出这些循环,因为那些循环会增加实施所需的工作量。

其次,添加CGContextRef context = UIGraphicsGetCurrentContext();作为该drawRect方法的第一行。

所以你的实现看起来应该更好:

- (void)drawRect:(CGRect)rect 
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, 0, rect.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);

    int firstCol = floorf(CGRectGetMinX(rect) / tileSize);
    int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize);
    int firstRow = floorf(CGRectGetMinY(rect) / tileSize);
    int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize);

    for( int row = firstRow; row <= lastRow; row++ ) 
    {
        for( int col = firstCol; col <= lastCol; col++ ) 
        {
            UIImage = [self getTileWithRow:row column:col];

            CGRect tileRect = CGRectMake((col * tileSize), 
                                         row * tileSize),
                                         tileSize, tileSize);

            CGContextDrawImage(context, tileRect, tile.CGImage);
        }
    }
    CGContextRestoreGState(context);
}