我试图在自定义视图的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年前的事情,我想知道自那时以来是否有任何改变。
答案 0 :(得分:1)
您可以做的是将路径视为数据,即每当有影响树的更改(例如添加分支)时,重新计算路径并重绘,这样您只需支付1秒的罚款。 / p>
基本上,您需要重构drawBranch
函数,而不是将绘制到上下文中,返回CGPath
个对象。然后可以将其保留在视图上并在drawRect:
方法中重新绘制。
另一种选择是使用CATiledLayer,但这假设你能够一次只绘制部分视图(例如,你可以将绘图分成100x100像素的图块)。这不一定会使它更快,但它可以避免绘制当前不可见的树的部分,只在需要时绘制它们。
简而言之,尝试将确定树的路径(模型)的逻辑与表示(将其绘制到CGContext
)分开。完全有可能生成树路径是一项昂贵的操作,但至少通过将其与绘图分开,可以避免阻塞主线程,并确保尽可能不频繁地进行耗时的计算。 / p>