【问题标题】:Large UIBezierPath, slow renderingUIBezierPath 大,渲染慢
【发布时间】:2015-04-16 14:18:33
【问题描述】:

对于我正在创建的应用程序,我使用UIBezierPath 来存储路径。问题是这条路径的长度不断增加,并且在某一点上,应用程序滞后并变得生涩。因为路径的长度不断增加,我不断地每秒重绘视图 100 次(如果有更好的方法,请告诉我)。在某个时刻,应用程序变得非常生涩。我认为是因为路径太长了。

您可以在我的drawRect 方法中看到图形已被翻译。屏幕上的路径很少,所以有没有办法只描边可见的路径部分?这就是我认为我使用 CGContextClip 方法所做的事情,但它没有明显的改进。

- (void)drawRect:(CGRect)rect {
    CGContextRef myContext = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(myContext, 0, yTranslation);
    [[UIColor whiteColor] setStroke];
    [bPath addLineToPoint:currentPoint];
    [bPath setLineWidth:lineWidth];
    CGContextClip(myContext);
    [bPath stroke];
}

谢谢。

【问题讨论】:

  • @Rob 是的,该行与用户的点击有关。我有一个定时方法,每 10 毫秒调用一次来刷新屏幕并根据用户的最后一次点击进行调整。但无论如何,路径永远不会是静态的。另外,我只是添加点,整个曲线没有改变。谢谢。
  • @Rob 应用程序的性质需要添加这些数据点。我确实将更新从 10 毫秒更改为 40 毫秒,并且有了显着的改进。但是,我的理想方案是缩短到屏幕上可见内容的路径。

标签: ios cocoa-touch graphics core-graphics uibezierpath


【解决方案1】:

缓存是一种可能的解决方案:在具有透明背景的内存图像上绘制一次曲线。仅在曲线发生变化时更新此图像。将此缓存的图像覆盖在您正在绘制的任何内容上。它的处理能力应该更便宜。

另一种可能性是在确定哪些点会影响当前视图后,从贝塞尔曲线中删除不需要的点,然后渲染生成的贝塞尔曲线。

【讨论】:

  • 是的,但曲线是不断变化的。这还有帮助吗?我觉得我不太明白。我的图形知识有限
  • 每秒变化100次吗?
  • 是的,但我可以改变它
  • 有没有办法只描边路径的可见部分?
  • 你是在告诉我曲线的长度每秒增加 100 次,而你每秒重绘 100 次?在这种情况下,您需要确定哪些控制曲线路径的点对当前视图没有影响,并在绘制之前将它们预先移除。
【解决方案2】:

一些想法:

  1. 恕我直言,您根本不应该定期添加数据点。当且仅当要添加新数据点时,您才应该添加数据点(例如touchesMoved 或使用UIGestureStateChanged 调用手势识别器)。这减少了贝塞尔曲线的点数,并推迟了性能问题强加给您的点。该过程应该由触摸事件驱动,而不是计时器。

  2. 如果您的某些绘图不在屏幕上,您可以通过检查其中任何一个点是否位于视图的可见部分(例如CGRectContainsPoint)来加快绘图速度。您可能应该检查线段与CGRect 的交点(因为理论上起点和终点都不可能在可见矩形内,但它们之间的线段可能与矩形相交)。

    您还可以设计此过程,以便它确定哪些段仅在视口移动时可见。这可以让您无需不断地遍历一个非常大的数组。

  3. 在某些时候,与位图图像相比,绘制单个路径的回报会递减,即使只是对于可见部分也是如此。有时将旧路径渲染为图像很有用,然后在该快照上绘制新路径,而不是每次都重新绘制整个路径。例如,我使用的方法是,当我开始一个新手势时,我对旧图像进行快照并仅在其上绘制新手势。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多