drawRect和CGGraphicsContext如何工作? [英] How does drawRect and CGGraphicsContext work?

查看:106
本文介绍了drawRect和CGGraphicsContext如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理Core Graphic的某些内容,并且我希望就一些主题进行其他说明。



drawRect:
我已经了解了这一点,并且知道UIView的所有绘图方面都在这里,但是不清楚是什么发生在幕后。创建UIView并填写drawRect然后将另一个对象的UIView设置为该自定义视图时会发生什么情况?何时调用drawRect?



CGGraphicsContext:
我知道这是什么目的,并且理解了这个概念,但是我无法确切知道它是如何工作的。
例如:

  CGContextSaveGState(context); 
CGContextAddRect(context,rect);
CGContextClip(context);
CGContextDrawLinearGradient(context,gradient,startPoint,endPoint,0);
CGContextRestoreGState(context);

上面的代码在我的应用中,可以正常工作。让我感到困惑的是它的工作方式。保存/还原上下文的想法很有意义,但是看起来我确实是在保存一个上下文,使用完全相同的上下文进行更改,然后再次还原相同的上下文。好像我要保存一个上下文,然后在该上下文上书写,只是为了还原它。如何将其保存到还原时的状态,即它是上下文的实例,而不是用于更改的实例?您在每种情况下都使用变量上下文的相同引用。



最后,我非常感谢实践项目或示例使用Core Graphics的任何资源。我正在寻求提高自己的技能,因为目前我显然没有太多。

解决方案


当我创建一个UIView并填写drawRect然后将另一个对象的UIView设置为该自定义视图时会发生什么?何时调用drawRect?


在实时视图图中添加视图会将视图的框架标记为需要显示。然后,主运行循环创建并合并无效的矩形,并很快返回以调用图形。失效后不会立即绘制。这是一件好事,因为例如调整大小会导致严重的透支-多余的工作会破坏许多应用程序的绘画性能。在绘制时,会创建一个要渲染的上下文-最终输出到其目的地。目标可以是设备/屏幕,位图,PDF等。但是,上下文句柄( CGContextRef )本身引用目标,并持有一组有关其状态的参数(这些参数都记录在这里)。这些参数集的操作类似于堆栈:Push = CGContextSaveGState ,Pop = CGContextRestoreGState 。尽管上下文指针没有更改,但是参数集的堆栈也在更改。



关于资源,请参见使用Quartz编程。它已经8岁了,最初是为OS X编写的-但最终并没有多大关系,因为从那时起绘图系统和API的基础并没有真正显着发展-这就是您的意图专注在。 API已进行了扩展,因此最好回顾一下自10.4以来引入的API,看看它们解决了什么问题,但是对您来说这是秘密的一件好事,因为它有助于保持对绘图系统基本操作的关注。请注意,iOS排除了某些功能(例如,我认为通常是由于浮点性能和内存限制),因此每个示例可能无法在iOS上使用,但我知道没有更好的指南。



提示:如果您使用Quartz而不是AppKit / UIKit,则可以在OS X和iOS上轻松重用您的绘图代码。另外,Quartz API的更新频率较低(即,这些API的寿命更长)。


I am working with some stuff in Core Graphic's and I am looking for some additional clarification regarding a couple of topics.

drawRect: I have an understanding of this and know it is where all of the drawing aspect's of a UIView goes, but am just unclear as to what is happening behind the scene's. What happen's when I create a UIView and fill out drawRect then set another object's UIView to be that custom view? When is drawRect being called?

CGGraphicsContext: I know what the purpose of this is and understand the concept, but I can't see exactly how it is working. For example:

CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);

The code above is in my app and work's correctly. The thing that confuses me is how it is working. The idea of saving/restoring a context makes sense, but it appears like I am literally saving a context, using that exact same context to make change's, then restoring the same context once again. It just seem's like I am saving a context and then writing on top of that context, only to restore it. How is it getting saved to a point where when you restore it, it is a different instance of the context than what was just used to make changes? You use the same reference of the variable context in every situation.

Lastly I would appreciate any resource's for practice project's or example's on using Core Graphics. I am looking to improve my skill in the matter since I obviously don't have much at the current time.

解决方案

What happen's when I create a UIView and fill out drawRect then set another object's UIView to be that custom view? When is drawRect being called?

Adding a view to a 'live' view graph marks the view's frame as in need of display. The main run loop then creates and coalesces invalid rects and soon returns to invoke drawing. It does not draw immediately upon invalidation. This is a good thing because resizing, for example, would result in significant overdrawing -- redundant work which would kill many apps' drawing performance. When drawing, a context is created to render to -- which ultimately outputs to its destination.

Graphics Contexts are abstractions which are free to work optimally for their destination -- a destination could be a device/screen, bitmap, PDF, etc.. However, a context handle (CGContextRef) itself refers to a destination and holds a set of parameters regarding its state (these parameters are all documented here). These parameter sets operate like stacks: Push = CGContextSaveGState, Pop = CGContextRestoreGState. Although the context pointer isn't changing, the stack of parameter sets is changing.

As far as resources, see Programming with Quartz. It's 8 years old now, and was originally written for OS X -- but that ultimately doesn't matter a whole lot because the fundamentals of the drawing system and APIs really haven't evolved significantly since then -- And that is what you intend to focus on. The APIs have been extended, so it would be good to review which APIs were introduced since 10.4 and see what problems they solve, but it's secretly a good thing for you because it helps maintain focus on the fundamental operation of the drawing system. Note that some functionalities were excluded from iOS (e.g. often due to floating point performance and memory constraints, I figure), so every example may not be usable on iOS, but I know of no better guide.

Tip: Your drawing code can be easily reused on OS X and iOS if you use Quartz rather than AppKit/UIKit. Plus, the Quartz APIs have a lower update frequency (i.e. the APIs tend to be longer lived).

这篇关于drawRect和CGGraphicsContext如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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