Quartz 2D drawRect方法(iPhone) [英] Quartz 2D drawRect method (iPhone)

查看:91
本文介绍了Quartz 2D drawRect方法(iPhone)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面前有4本不同的 iPhone / Cocoa / Core Animation / Objective-C 书籍,以及来自网络的大量示例代码。但不知何故,我仍然觉得我缺少对绘图如何在 Quartz 2D 中工作的基本理解。

I've got 4 different iPhone/Cocoa/Core Animation/Objective-C books in front of me, along with numerous sample code from the web. Yet somehow I still feel like I'm missing some fundamental understanding of how drawing works in Quartz 2D.

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

Is drawRect() meant to simply be a hook in which to execute your drawing code? Or is this method supposed to also redraw regions that are "damaged", and need repainting? Can I just draw my stuff once and then it "sticks", or must I repaint the whole scene at any time via drawRect()? Java's Graphics2D object works this way- you must draw your whole "image" every time paint() is called, so you must be prepared to re-construct it at any time (or cache it).

您如何实施简单的绘图程序?您是否必须记住用户绘制的每一行/点/笔画,并且每次调用 drawRect()时都会复制它? 离屏渲染怎么样;你可以完成你的所有绘图然后调用 [self setNeedsDisplay] 将你的写入刷新到屏幕上吗?

How would you implement a simple drawing program? Would you have to "remember" each line/point/stroke that the user drew, and replicate that each time drawRect() is called? How about "offscreen" rendering; can you do all your drawing and then call [self setNeedsDisplay] to have your writes flushed to the screen?

让我们说,为了响应用户的触摸,我想在他触摸的屏幕上放一个X。 X应保留在那里,每次新触摸都会生成另一个X.我是否需要记住所有这些触摸坐标,然后在 drawRect()中绘制所有这些坐标?

Let's say that in response to a user's touch, I want to put an "X" on the screen where he touched up. The X should remain there, and each new touch produces another X. Do I need to remember all these touchup coordinates and then draw them all in drawRect() ?

编辑:

除非我误解,否则joconor和Hector Ramos的回答都是相互矛盾的其他。这很好地证明了我对这个问题的困惑。 : - )

Unless I've misunderstood, joconor and Hector Ramos's answers below are contradicting each other. And that's a good demonstration of my confusion concerning this subject. :-)

推荐答案

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

Some of the confusion between various Cocoa references comes from the introduction of layer-backed views in Leopard. On the iPhone, all UIViews are layer-backed, where in Leopard views need to manually enable layer-backing.

对于图层支持的视图,使用一次性绘制内容您在 drawRect()中提供的任何内容,但随后会缓冲到图层中。该图层的作用类似于矩形纹理,因此当您移动图层支持的视图或覆盖它时,不需要重绘,纹理只是通过GPU移动到该位置。除非您为图层设置 needsDisplayOnBoundsChange属性 YES ,否则更改图层(或其包含视图)的大小将简单地缩放内容。这可能会导致视图或图层中的图形模糊,因此您可能希望在这种情况下强制重绘。 setNeedsDisplay 将触发手动重绘视图或图层的内容,并随后在图层中重新浏览该内容。

For a layer-backed view, content is drawn once using whatever you supplied in drawRect(), but then is buffered into the layer. The layer acts like a rectangular texture, so when you move the layer-backed view or cover it, no redraw is needed, the texture is just moved to that location via the GPU. Unless you set the needsDisplayOnBoundsChange property to YES for a layer, changing the size of the layer (or its containing view) will simply scale the contents. This may lead to blurry graphics within your view or layer, so you may want to force a redraw in this case. setNeedsDisplay will trigger a manual redraw of the view's or layer's content, and a subsequent recaching of that content in the layer.

为了获得最佳性能,建议您避免频繁调用 drawRect ,因为在图层中进行Quartz绘图和重新计算是昂贵的操作。最好尝试使用可以移动或缩放的单独图层来制作动画。

For optimal performance, it's suggested that you avoid having frequent calls to drawRect, because Quartz drawing and recaching in a layer are expensive operations. It's best to try to do animation using separate layers that you can move around or scale.

您看到的与桌面相关的基于Cocoa的引用可能假设为非支持图层的视图,它可以调用drawRect:视图需要更新时,无论是移动,缩放还是部分视图都被遮挡。正如我所说的,所有的UIView都是图层支持的,所以在iPhone上并非如此。

The Cocoa-based references you've seen that relate to the desktop may assume non-layer-backed views, which do call drawRect: any time the view needs to be updated, whether that's from movement, scaling, or having part of the view obscured. As I said, all UIViews are layer-backed, so this is not the case on the iPhone.

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

That said, for your drawing application, one way to do it would be to maintain an array of drawn objects and call drawRect: each time the user adds something new, iterating over each of the previously drawn objects in order. I might suggest an alternative approach where you create a new UIView or CALayer for each drawing operation. The contents of that drawing operation (line, arc, X, etc.) would be drawn by the individual view or layer. That way, you won't have to redraw everything on a new touch, and you might be able to do some neat vector-style editing by moving each of the drawn elements around independently of the others. For complex drawings, there might be a bit of a memory tradeoff in this, but I'd bet that it would have much better drawing performance (minimal CPU usage and flickering).

这篇关于Quartz 2D drawRect方法(iPhone)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆