背景:我有一个自定义 ScrollView (子类),其上有可拖动的 uiimageviews,基于我需要在 uiscrollview 的 subview 中动态绘制一些线条的拖动。 (请注意,我需要将它们放在 subview 中,因为稍后我需要更改 View 的不透明度。)
因此,在我花费大量时间开发代码之前(我是新手,所以这需要我一段时间),我研究了我需要做什么并找到了一些可能的方法。只是想知道执行此操作的正确方法是什么。
- 创建 UIView 的子类并使用 drawRect 方法绘制我需要的线条(但不确定如何使其动态读取值)
- 在 subview 上使用 CALayers 并在那里绘图
- 使用 CGContext 函数创建画线方法
- 还有别的事吗?
为帮助干杯
最佳答案
从概念上讲,您的所有主张都是相似的。所有这些都会导致以下步骤(其中一些是由 UIKit 无形地完成的):
- 在内存中设置位图上下文。
- 使用 Core Graphics 将线条绘制到位图中。
- 将此位图复制到 GPU 缓冲区(纹理)。
- 使用 GPU 构建图层( View )层次结构。
上述步骤中最昂贵的部分是前三点。它们会导致重复的内存分配、内存复制和 CPU/GPU 通信。另一方面,你真正想做的是轻量级的:画一条线,可能动画开始/结束点,宽度,颜色,alpha,...
有一个简单的方法可以做到这一点,完全避免所描述的开销:为您的线条使用 CALayer,但不用在 CPU 上重新绘制内容,只需用线条的颜色完全填充它(设置其 backgroundColor
属性设置为线条的颜色。然后修改图层的位置、边界、变换属性,使 CALayer 准确覆盖线条的区域。
当然,这种方法只能画直线。但也可以通过将 contents
属性设置为图像来修改它以绘制复杂的视觉效果。例如,使用这种技术,您可以在线上获得发光效果的模糊边缘。
虽然这种技术有其局限性,但我在 iPhone 和 Mac 上的不同应用程序中经常使用它。它始终比基于核心图形的绘图具有显着优越的性能。
编辑:计算图层属性的代码:
void setLayerToLineFromAToB(CALayer *layer, CGPoint a, CGPoint b, CGFloat lineWidth)
{
CGPoint center = { 0.5 * (a.x + b.x), 0.5 * (a.y + b.y) };
CGFloat length = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
CGFloat angle = atan2(a.y - b.y, a.x - b.x);
layer.position = center;
layer.bounds = (CGRect) { {0, 0}, { length + lineWidth, lineWidth } };
layer.transform = CATransform3DMakeRotation(angle, 0, 0, 1);
}
第二次编辑: Here's a simple test project这显示了 Core Graphics 和基于 Core Animation 的渲染在性能上的巨大差异。
第三次编辑:结果非常令人印象深刻:渲染 30 个可拖动 View ,每个 View 彼此连接(产生 435 条线),使用 Core Animation 在 iPad 2 上以 60Hz 流畅渲染。使用经典方法时,帧速率降至 5 Hz,并且最终会出现内存警告。
关于iphone - 在 View 之间划线的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5847876/