drawRect() 是否只是一个执行绘图代码的钩子?
它旨在使用当前图形上下文堆栈重绘传递给您的区域(矩形)。不再。
或者这种方法是否应该也重绘“损坏”的区域,需要重绘?
不会。如果脏区不重叠,您可能会收到多个调用,drawRect:
其中传递给您的不同矩形。使用 使矩形无效setNeedsDisplayInRect:
。如果只需要重新绘制视图表面的一部分,那么当需要绘制时,您将被要求绘制该部分。
我可以只画一次然后它“粘住”,还是必须随时通过 drawRect() 重新绘制整个场景?
它不“粘”。矩形在您的应用执行期间变得无效,并且当视图系统需要更新屏幕时,您需要重新绘制这些矩形。您只重绘请求的矩形。
在某些情况下,一个简单的实现可能(相当懒惰地)使视图的整个矩形无效,只要一部分无效。这通常很糟糕,因为它通常需要比必要更多的绘图,并且当视图不透明时尤其浪费。
Java 的 Graphics2D 对象以这种方式工作 - 每次调用 paint() 时都必须绘制整个“图像”,因此您必须随时准备重新构建它(或缓存它)。
AppKit 或 UIKit 并非如此。
你将如何实现一个简单的绘图程序?您是否必须“记住”用户绘制的每条线/点/笔划,并在每次调用 drawRect() 时复制它们?
您必须记住绘制视图所需的上下文(例如,每条线/点/笔划)。您只需要绘制所请求的区域。从技术上讲,如果您要在该矩形之外绘制,图形系统不会抱怨,但这可能会导致伪影。
对于复杂的渲染,绘制到外部缓冲区(例如位图)可能更容易或更有效,然后使用预渲染的位图表示在drawrect:
. (另请参阅 Brad 对图层的回答)
“离屏”渲染怎么样?你能完成所有的绘图然后调用 [self setNeedsDisplay] 将你的写入刷新到屏幕上吗?
是的,你可以这么做。具体来说,您将渲染到外部缓冲区(例如位图),当您完成对位图的渲染时,使您希望绘制的矩形无效,然后在drawRect:
调用时使用位图中的数据绘制到屏幕。
假设为了响应用户的触摸,我想在他触摸的屏幕上放置一个“X”。X 应该保留在那里,并且每次新的触摸都会产生另一个 X。我是否需要记住所有这些修饰坐标,然后将它们全部绘制在 drawRect() 中?
好吧,你有几个选择。您的建议是一个(假设您在传递给您的矩形内绘制)。另一种方法是创建一个“X”视图,如果您需要这些 X 在启动过程中持续存在,只需记住重建视图所需的点即可。在许多情况下,您可以轻松地将复杂的问题分成几层(简单的 2D 游戏):
- 1)具有地平线的背景图像。
- 2)前台的一些东西不经常改变。
- 3) 用户用于在游戏中导航的角色。
因此,大多数问题都可以轻松划分,因此您不必一直渲染所有内容。如果做得好,这会降低复杂性并提高性能。如果做得不好,可能会更糟。