绘制多行时的drawRect性能

时间:2015-07-24 20:59:53

标签: ios core-graphics fractals

我试图在自定义视图的drawRect方法中绘制程序生成的树。这非常适合大约20k行。除此之外,绘画性能完全进入了crapper(即绘制树的时间接近1000ms)。

绘制树的绘图代码是:

func drawBranch( branch: Branch, context :CGContext ) {        
    CGContextMoveToPoint(context,    (branch.originPoint().x), (branch.originPoint().y))
    CGContextAddLineToPoint(context, (branch.endPoint().x), (branch.endPoint().y))

    for b in branch.children {
        drawBranch(b, context: context)
    }
}

override func drawRect(rect: CGRect) {
    print("\(NSDate()) drawRect")

    // Setup graphics context
    let ctx = UIGraphicsGetCurrentContext()

    // clear context
    CGContextClearRect(ctx, rect)

    CGContextSetRGBFillColor(ctx, 0.0, 0.0, 0.0, 1.0)

    CGContextFillRect(ctx, rect)

    CGContextSaveGState(ctx);
    CGContextTranslateCTM(ctx, 0.0, rect.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);
    CGContextSetShouldAntialias(ctx, true)


    CGContextSetRGBStrokeColor(ctx, 0.3, 0.3, 0.3, 1)

    if let tree = self.tree {
        drawBranch(tree, context: ctx)
    }

    CGContextStrokePath(ctx)
    CGContextRestoreGState(ctx);
}

对于这种速度有没有希望,或者我应该在很久以前放弃并继续使用其他渲染方法/引擎?

我通读this question here这似乎意味着它永远不会起作用,但那是3年前的事情,我想知道自那时以来是否有任何改变。

1 个答案:

答案 0 :(得分:1)

您可以做的是将路径视为数据,即每当有影响树的更改(例如添加分支)时,重新计算路径并重绘,这样您只需支付1秒的罚款。 / p>

基本上,您需要重构drawBranch函数,而不是将绘制到上下文中,返回CGPath个对象。然后可以将其保留在视图上并在drawRect:方法中重新绘制。

另一种选择是使用CATiledLayer,但这假设你能够一次只绘制部分视图(例如,你可以将绘图分成100x100像素的图块)。这不一定会使它更快,但它可以避免绘制当前不可见的树的部分,只在需要时绘制它们。

简而言之,尝试将确定树的路径(模型)的逻辑与表示(将其绘制到CGContext)分开。完全有可能生成树路径是一项昂贵的操作,但至少通过将其与绘图分开,可以避免阻塞主线程,并确保尽可能不频繁地进行耗时的计算。 / p>