使用CGContext什么方式来绘制比较合适?
我知道CGContext不能直接调用它进行绘制,需要在drawInContext中填充绘制逻辑,并使用“setNeedsDisplay”调用CGContext进行绘制,所以,我设计了一个cmd来执行,但它导致了一些问题。 ..像这样:
为什么我不能画一个循环? (在iPhone中使用UIView)
我认为CGContext与我以前的编程经验非常不同....(我使用HTML5画布,它允许我添加更多细节,在绘制之后,Java Swing也是如此) 其实我想知道在苹果程序员的心目中什么才是适合实现这种东西的。太。
I know that the CGContext cannot call it to draw directly, and it needs to fill the drawing logic in the drawInContext, and call the CGContext to draw using "setNeedsDisplay", so, I designed a cmd to execute, but it cause some problems... like this :
Why I can't draw in a loop? (Using UIView in iPhone)
I think the CGContext is very different from my previous programming experience....(I used HTML5 canvas, that allow me add more details, after I draw, so do the Java Swing)
Actually, I want to know what is the suitable to implement these kind of thing in Apples' programmer mind. Thz.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于你所问的问题,有三种方法。您可以在
drawRect:
中绘制所有内容,可以管理多个图层,也可以在图像中绘制。每种方法都有优点,但首先您需要正确思考问题,以免破坏性能。绘画不断发生。每次发生变化时,都可能需要做大量的绘图。通常不是整个屏幕,但仍然有很多绘图。由于
drawRect:
和drawInContext:
可以被多次调用,因此它们需要高效。这意味着您不想进行大量昂贵的计算,也不想进行大量无用的绘图。 “无用”意味着“实际上不会显示,因为它在屏幕外或被其他绘图遮挡”。因此,在通常情况下,您将实际的绘图代码放在
drawRect:
中,但您在其他地方(通常是在数据更改时)进行所有计算。例如,每当数据发生变化时,您都会读取文件、计算出坐标、创建 CGPath 等(这应该比绘图的频率要低得多)。您将所有结果保存到 ivars 中,然后在drawRect:
中绘制最终结果。因此,在您的循环示例中,您的视图对象中可能有一个 NSArray 图像,并且在drawRect:
中您将按顺序绘制它们。另一种方法是为每个图像创建一个单独的图层,将图像设置为内容,然后将图层附加到视图。到那时你就完成了。您不再需要编写绘图代码。 Quartz 非常有效地处理层,因此这可以成为解决各种问题的非常好的解决方案。
最后,您可以将所有内容合成为图像,然后将该图像粘贴到图像视图中,或者直接在视图中绘制图像,或者将图像附加到图层中。如果您有非常复杂的绘图(特别是使用 CGPath),这是一个很好的解决方案。如果您不断更改内容,这可能会很昂贵,因为您必须创建一个新的图像上下文,将旧图像绘制到新的上下文中,在其上绘制,然后从上下文创建一个新图像。但这对于不经常更改的复杂绘图很有用。
但你是对的,CGContext 不像画布。每个绘制周期都需要重新绘制。您可以自己执行此操作,也可以使用另一个视图对象(如 UIImageView)来执行此操作。但这必须以某种方式完成。
There are three approaches to what you're asking. You can draw everything in
drawRect:
, you can manage multiple layers, or you can draw in an image. Each has advantages, but first you need to think correctly about the problem so that you don't destroy performance.Drawing happens constantly. Every time anything changes, there may be quite a lot of drawing that has to be done. Not the whole screen usually, but still a lot of drawing. Since
drawRect:
anddrawInContext:
can be called many times, they need to be efficient. That means that you don't want to do a lot of expensive calculations, and you don't want to do a lot of useless drawing. "Useless" means "won't actually be displayed because it's off screen or obscured by other drawing."So in the usual case, you put your actual drawing code in
drawRect:
, but you do all your calculations elsewhere, generally when your data changes. For example, you read your files, figure out your coordinates, create CGPaths, etc whenever your data changes (which should be much less frequent then drawing). You save all the results into ivars, and then indrawRect:
you just draw the final result. So in your loop example, you would probably have an NSArray of images in your view object, and indrawRect:
you would draw them all in order.Another approach is to create a separate layer for each image, set the image as the content, and then attach the layer to the view. You're done at that point. There is no more drawing code you need to write. Quartz handles layers very efficiently, so this can be a very good solution to a wide variety of problems.
Finally, you can composite everything into an image, and then stick that image in an image view, or draw the image directly in the view, or attach the image to a layer. This is a good solution if you have very complicated drawing (particularly using CGPath). This can be expensive if you're constantly changing things, since you have to create a new image context, draw the old image into the new context, draw on top of it, and then create a new image from the context. But it's good for a complicated drawing that doesn't change often.
But you're correct, CGContext is not like a canvas. It needs to be redrawn every draw cycle. You can do that yourself, or you can use another view object (like UIImageView) to do it for you. But it has to be done one way or another.