在CATiledLayer上有效地绘制CGPath

时间:2012-02-03 12:55:59

标签: iphone objective-c cocoa-touch core-graphics

如何在CGPath上有效地绘制CATiledLayer?我正在检查磁贴的边界框是否与路径的边界框相交:

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context {
    CGRect boundingBox = CGPathGetPathBoundingBox(drawPath);
    CGRect rect = CGContextGetClipBoundingBox(context);

    if( !CGRectIntersectsRect(boundingBox, rect) )
        return;

    // Draw path...
}

这不是很有效,因为多个线程多次调用drawLayer:inContext:并导致多次绘制路径。

有更好,更有效的方法吗?

2 个答案:

答案 0 :(得分:5)

最简单的选择是将曲线绘制成大图像,然后平铺图像。但是如果你是平铺,那可能意味着图像太大了,或者你刚刚在第一时间绘制了路径,对吧?

所以你可能需要分开你的路径。最简单的方法是使用CGPathApply逐元素地将其拆分。对于每个元素,您可以检查其边界框并确定该元素是否属于您的边界。如果没有,只需跟踪最后一个终点即可。如果是,则移动到您看到的最后一个结束点,并将该元素添加到此图块的新路径中。完成后,每个图块都会绘制自己的路径。

从技术上讲,你会在这里“画出”超出界限的东西(例如延伸到瓷砖之外的线条),但这比听起来便宜得多。 Core Graphics将非常容易地剪辑单个元素。目标是避免计算完全不在边界框中的元素。

请务必缓存生成的路径。您不需要计算每个图块的路径;只是你画的那些。但是每次瓦片绘制时都要避免重新计算。只要数据发生更改,就转储缓存。如果有非常多的图块,您还可以使用NSCache来更好地优化图块。

答案 1 :(得分:2)

您不会显示路径的创建位置。如果可能,您可以尝试在-drawLayer:inContext:方法中构建路径,仅创建绘制图块所需的部分。

与所有性能问题一样,您应该使用Instruments来分析代码并找出瓶颈的确切位置。你有没有尝试过,如果是的话,你找到了什么?

作为旁注,您是否有使用CGPath而不是UIBezierPath的原因?来自Apple's documentation

  

要在iOS中创建路径,建议您使用UIBezierPath   除非你需要一些功能,否则不是CGPath函数   只有Core Graphics提供,例如向路径添加省略号。   有关在UIKit中创建和渲染路径的更多信息,请参阅“绘制形状”   使用Bezier路径。“