我面前有4本不同的iPhone/Cocoa/Core Animation/Objective-C书籍,以及来自网络的大量示例代码.然而,不知何故,我仍然觉得我缺少对Quartz 2D中绘图如何工作的基本理解.
是否drawRect()
只是一个执行绘图代码的钩子?或者这种方法是否也应该重绘"受损"的区域,并且需要重新绘制?我可以只画一次我的东西,然后它"粘",或者我必须随时重绘整个场景drawRect()
吗?Java的Graphics2D对象以这种方式工作 - 每次调用paint()时都必须绘制整个"图像",因此您必须准备随时重新构造它(或缓存它).
你会如何实现一个简单的绘图程序?你是否必须"记住"用户绘制的每一行/点/笔划,并复制每次drawRect()
调用?"离屏"渲染怎么样; 你可以做你所有的绘图,然后打电话[self setNeedsDisplay]
让你的写作刷新到屏幕上吗?
让我们说,为了响应用户的触摸,我想在他触摸的屏幕上放一个"X".X应该保留在那里,每次新的触摸产生另一个X.我是否需要记住所有这些触摸坐标然后全部绘制drawRect()
?
编辑:
除非我误解,否则joconor和Hector Ramos的回答是相互矛盾的.这很好地证明了我对这个问题的困惑.:-)
各种Cocoa引用之间的一些混淆来自Leopard中引入的层支持视图.在iPhone上,所有UIView都是图层支持的,其中Leopard视图需要手动启用图层支持.
对于图层支持的视图,使用您提供的内容绘制一次内容drawRect()
,然后缓冲到图层中.该图层的作用类似于矩形纹理,因此当您移动图层支持的视图或覆盖它时,不需要重绘,纹理只是通过GPU移动到该位置.除非为图层设置needsDisplayOnBoundsChange property
to YES
,否则更改图层(或其包含视图)的大小将只是缩放内容.这可能会导致视图或图层中的图形模糊,因此您可能希望在这种情况下强制重绘.setNeedsDisplay
将触发手动重绘视图或图层的内容,以及随后在图层中重新捕获该内容.
为了获得最佳性能,建议您避免频繁调用drawRect
,因为Quartz绘图和层中的重新捕获是昂贵的操作.最好尝试使用可以移动或缩放的单独图层来制作动画.
您看到的与桌面相关的基于Cocoa的引用可能会假设非层支持的视图,它们会调用drawRect:任何时候需要更新视图,无论是来自移动,缩放还是部分视图模糊.正如我所说的,所有UIView都是图层支持的,所以在iPhone上并非如此.
也就是说,对于您的绘图应用程序,一种方法是维护绘制对象的数组并调用drawRect:每次用户添加新内容时,按顺序迭代每个先前绘制的对象.我可能会建议一种替代方法,为每个绘图操作创建一个新的UIView或CALayer.该绘图操作的内容(线,弧,X等)将由单个视图或图层绘制.这样,您就不必在新的触摸上重绘所有内容,并且您可以通过独立于其他元素移动每个绘制的元素来进行一些整洁的矢量样式编辑.对于复杂的绘图,可能会有一些内存权衡,但我敢打赌它会有更好的绘图性能(最小的CPU使用率和闪烁).