实现 Keynote 等绘图功能的最佳方式

Posted

技术标签:

【中文标题】实现 Keynote 等绘图功能的最佳方式【英文标题】:The best way to implement drawing features like Keynote 【发布时间】:2010-05-10 07:30:23 【问题描述】:

我正在尝试制作一个用于绘制简单几何对象(矩形、圆角矩形、椭圆、星形...)的 iPad 小工具。 我的目标是做一些非常接近 Keynote(绘图功能)的东西,即让用户添加一个矩形(例如),调整它的大小并移动它。我也希望用户可以选择许多对象并将它们一起移动。

我已经考虑了至少 3 种不同的方法来做到这一点:

为每种对象类型扩展 UIView,为 Rect 扩展一个类,为 Ellipse 扩展另一个类,... 使用自定义绘图方法。然后将此视图添加为全局视图的子视图。 为每种对象类型扩展 CALayer,为 Rect 扩展一个类,为 Ellipse 扩展另一个类,... 使用自定义绘图方法。然后将该层添加为全局视图层的子层。 为每种对象类型扩展 NSObject,为 Rect 扩展一个类,为 Ellipse 扩展另一个类,... 仅使用一个绘图方法,该方法将获得一个 CGContext 和一个 Rect 作为参数并直接在其中绘制表单。这些方法将被全局视图的绘图方法调用。

我知道前两种方法带有检测每个对象上的触摸的功能,可以轻松添加阴影,......但我担心它们有点太重了?这就是为什么我想到了最后一种方式,它似乎是直截了当的。

哪种方式效率更高???或者也许我没有想到其他方式?

任何帮助将不胜感激;-)

谢谢。

【问题讨论】:

【参考方案1】:

我会使用 UIKit 类来绘制您的绘图,然后从那里分析和优化您的代码。

Apple/iPad 信息:link text

【讨论】:

【参考方案2】:

我的第一感觉是采用第 3 种方式,但要确信,在我发布消息后,我仅使用全局视图和 200 多种几何形式(矩形、圆角矩形和椭圆)进行了一些测试它和我在 touchMoved 事件中只移动了一半。我使用方式 1(子类化 UIView)和方式 3(子类化 NSObject)进行了此测试,方式 2 在我看来过于严格,根本无法帮助我。 结果是方式1似乎更有效......当我一起移动60个物体时没有滞后!此外,使用这种方式可能会对我有所帮助,因为使用视图会带来一些有趣的功能,例如复杂路径上的触摸检测(参见 UIBezierPath)、由 UIView 类处理的对象层次结构......

所以我将使用这种方式并回到这里分享我的结果;-)

问候

【讨论】:

【参考方案3】:

最好使用 CGLayer 对象。好处是:

    它速度更快,内存效率更高。对于简单的对象,添加视图的成本要高得多,并且会使视图层次结构复杂化。对于复杂的对象,在 CGLayers 上完成的缓存可以提高性能。

    将对象组合在一起很容易。您只需将所有内容都放在一个新图层中,瞧!几乎没有开销。

    使用 CGLayer 和其他 Quartz 对象可为您提供更大的灵活性。

唯一的缺点是你必须直接使用Quartz 2D。这不是很困难,但如果你以前没有使用过它需要一些学习。

【讨论】:

【参考方案4】:

CAShapeLayer 几乎可以处理您的选项 2。默认情况下,它会执行矩形和圆角矩形(请参阅cornerRadius),或者您可以为其指定任意形状的路径。对于您的选项 1,您可以将 CAShapeLayer 与 UIView 一起使用,而不是实现 drawRect,它可能会更快。

【讨论】:

以上是关于实现 Keynote 等绘图功能的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

在 HTML 上绘图的最佳方式是啥

生存/回归分析结果的最佳/有效绘图

在 Swift 中存储和引用绘图数据以在 UITableView 中使用的最佳方式

如何使用 CgLayer 进行最佳绘图

iOS:缓存下载的 RSS 消息的最佳方式

在 Qt 中绘制绘图的最佳方法是啥?