12

我一直在做一些iOS绘图的实验。为了做一个实践练习,我编写了一个 BarChart 组件。下面是类图(好吧,我不允许上传图片)所以让我用文字写出来。我有一个继承自 UIView 的 NGBarChartView,它有 2 个协议 NGBarChartViewDataSource 和 NGBarChartViewDelegate。代码位于https://github.com/mraghuram/NELGPieChart/blob/master/NELGPieChart/NGBarChartView.m

为了绘制 barChart,我将每个 barChart 创建为不同的 CAShapeLayer。我这样做的原因有两个,首先我可以创建一个 UIBezierPath 并将其附加到一个 CAShapeLayer 对象和两个,我可以通过使用 [Layer hitTest] 方法轻松跟踪 barItem 是否被触摸。该组件运行良好。但是,我对绘制条形图所采用的方法并不满意。因此这个笔记。我需要关于以下方面的专家意见

  1. 通过使用 CAShapeLayer 并创建 BarItems 我真的没有使用 UIGraphicsContext,这是一个好的设计吗?
  2. 我的方法将在 UIView 中创建几个 CALayers。根据性能,您可以在 UIView 中创建的 CALayer 的数量是否有限制。
  3. 如果一个好的替代方法是使用 CGContext* 方法,那么识别特定路径是否已被触及的正确方法是什么
  4. 从动画的角度来看,比如当你点击 Bar 时它会闪烁,是 Layer 设计更好还是 CGContext 设计更好。

非常感谢您的帮助。顺便说一句,您可以随意查看我的代码和评论。我很乐意接受任何改进的建议。

最好的,穆拉利

4

1 回答 1

17

IMO,一般来说,任何一种绘图形状都需要强大的处理能力。并且用 GPU 合成缓存的位图比重新绘制所有位图要便宜得多。所以在很多情况下,我们将所有的绘图缓存到一个位图中,而在 iOS 中,CALayer我们负责这件事。

无论如何,如果您的位图超过显存限制,Quartz无法一次合成所有图层。因此,Quartz 必须在多个阶段上绘制单个帧。这需要将一些纹理重新加载到 GPU 中。这可能会影响性能。我对此不确定,因为已知 iPhone VRAM 与系统 RAM 集成。无论如何,即使在这种情况下,它仍然需要更多的工作。如果系统内存不足,系统可以清除现有位图并要求稍后重绘它们。

  1. CAShapeLayerCGContext将代替您完成所有(我相信您的意思是)工作。如果您觉得需要更多较低级别的优化,您可以自己执行此操作。

  2. 是的。显然,一切都受到性能观点的限制。如果您使用具有大型 alpha 混合图形的数百个图层,则会导致性能问题。无论如何,通常不会发生这种情况,因为 GPU 加速了层组合。如果您的图形线不是那么多,并且它们基本上是不透明的,那么您会没事的。

  3. 您所需要知道的是,一旦图形绘图被合成,就没有办法将它们分解回来。因为合成本身是一种有损压缩的优化,所以你只有两个选择(1)当需要突变时重绘所有图形。或者(2)制作每个显示元素(如图形线)的缓存位图,并根据您的需要进行合成。这正是 CALayers 正在做的事情。

  4. 绝对基于层的方法要好得多。任何类型的自由图形绘制(即使是在 GPU 中完成)都需要比 GPU 进行的简单位图合成(将变成两个带纹理的三角形)更多的处理能力。当然,除非您的图层不超过视频内存限制。

我希望这有帮助。

于 2011-09-11T20:09:39.147 回答