UIBezierPath 大,渲染慢

Large UIBezierPath, slow rendering

对于我正在创建的应用程序,我使用 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];
}

谢谢。

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

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

几个想法:

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

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

    您还可以设计此过程,使其确定哪些段仅在视口移动时可见。这可以使您免于不断迭代非常大的数组。

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