代码之家  ›  专栏  ›  技术社区  ›  Limbic System

石英2D drawRect法(iPhone)

  •  32
  • Limbic System  · 技术社区  · 17 年前

    我有4个不同的 在我面前的书,以及众多的样本代码从网上。但不知何故,我还是觉得自己对绘画在现实生活中的运作缺乏一些基本的理解 石英2D

    drawRect() 仅仅是用来执行绘图代码的钩子?或者这种方法也应该重新绘制“损坏”的区域,并且需要重新绘制?我可以只画一次我的东西,然后它“粘住”,还是我必须在任何时候重新画整个场景通过 drawRect() ? Java的Graphics2D对象是这样工作的——每次调用paint()时都必须绘制整个“图像”,因此必须随时准备重新构造它(或缓存它)。

    drawRect() 叫什么名字?“屏幕外”渲染怎么样?你能画完所有的图然后打电话给我吗 [self setNeedsDisplay] 把你写的东西刷新到屏幕上?

    假设为了响应用户的触摸,我想在他触摸的屏幕上加一个“X”。记住,每一个X都会产生一个新的坐标 drawRect() ?

    除非我误解了,否则乔科纳和赫克托·拉莫斯下面的回答是相互矛盾的。这很好地说明了我对这个问题的困惑。:-)

    4 回复  |  直到 14 年前
        1
  •  38
  •   pasawaya Katriel    14 年前

    各种Cocoa引用之间的一些混淆来自于Leopard中引入的层备份视图。在iPhone上,所有uiview都是层备份的,在Leopard视图中,需要手动启用层备份。

    对于层备份视图,使用中提供的任何内容绘制一次内容 drawRect() needsDisplayOnBoundsChange property YES 对于层,更改层(或其包含视图)的大小只会缩放内容。这可能会导致视图或图层中的图形模糊,因此在这种情况下可能需要强制重新绘制。 setNeedsDisplay

    为了获得最佳性能,建议您避免频繁调用 drawRect ,因为在一层中进行石英拉拔和再刻蚀是昂贵的操作。最好尝试使用可以移动或缩放的单独层来制作动画。

    您所看到的与桌面相关的基于Cocoa的引用可能采用非层备份视图,这些视图称为drawRect:任何时候都需要更新视图,无论是移动、缩放还是部分视图被遮挡。正如我所说的,所有uiview都是分层的,所以iPhone上不是这样。

    也就是说,对于绘图应用程序,一种方法是维护一个绘制对象的数组并调用drawRect:每次用户添加新的内容时,按顺序遍历以前绘制的每个对象。我可以建议另一种方法,即为每个绘图操作创建一个新的UIView或CALayer。绘制操作的内容(直线、圆弧、X等)将由单个视图或图层绘制。这样,您就不必在新的触摸屏上重新绘制所有内容,并且可以通过独立地移动每个绘制的元素来进行一些整洁的矢量样式编辑。对于复杂的绘图,这可能会有一点内存折衷,但我敢打赌它会有更好的绘图性能(最小的CPU使用和闪烁)。

        2
  •  4
  •   Héctor Ramos    17 年前

        3
  •  2
  •   Jay O'Conor    17 年前

    在拍摄时,一定要准备好画出合适的视野区域 drawRect: 被称为。

    图纸: 图纸: 图纸: 由于滚动和其他影响视图区域可见性的操作而变为可见时,将为视图的不同区域调用。

        4
  •  2
  •   justin    14 年前

    drawRect()只是一个执行绘图代码的钩子吗?

    它意味着使用当前图形上下文堆栈重新绘制传递给您的区域(rect)。再也没有了。

    或者这种方法也应该重新绘制“损坏”的区域,并且需要重新绘制?

    不可以。如果脏区域没有重叠,您可能会收到多个调用 drawRect: setNeedsDisplayInRect:

    我可以只画一次我的东西,然后它“粘住”,还是我必须在任何时候通过drawRect()重新绘制整个场景?

    在某些情况下,只要某个部分无效,一个简单的实现就可能(相当懒惰地)使视图的整个rect无效。这通常是不好的,因为它通常需要比需要更多的绘图,并且在视图不是不透明的情况下特别浪费。

    AppKit或UIKit则不然。

    如何实现一个简单的绘图程序?您是否需要“记住”用户绘制的每条线/点/笔划,并在每次调用drawRect()时复制这些线/点/笔划?

    对于复杂的渲染,可以更容易或更有效地绘制到外部缓冲区(例如位图),然后使用预渲染的位图表示来获取屏幕上的内容 drawrect: . (另请参见Brad关于图层的回答)

    是的,你能做到。具体来说,您可以渲染到外部缓冲区(例如位图),当您完成渲染到位图时,使要绘制的rect无效,然后使用位图中的数据绘制到屏幕上 被称为。

    嗯,你有几个选择。你的提议是一个(假设你在传递给你的rect内绘制)。另一种方法是创建一个“X”视图,只要记住重构视图所需的点就可以了,如果您需要这些X在不同的发布中保持不变的话。在许多情况下,您可以轻松地将复杂问题划分为多个层(简单的2D游戏):

    • 1) 地平线上的背景图像。
    • 3) 玩家用来在游戏中导航的角色。

    因此,大多数问题都可以很容易地划分,因此您不必一直渲染所有问题。如果做得好,这将降低复杂性并提高性能。如果做得不好,情况可能会更糟。