優(yōu)勢(shì)和限制
自定義UI提供能更大的繪制靈活性
自定義UI是計(jì)算密集型操作,不能充分利用GPU,所以盡可能少的使用本地圖形繪制技術(shù)。
Depending on the type of app you are creating, it may be possible to use little or no custom drawing code. Although immersive apps typically make extensive use of custom drawing code, utility and productivity apps can often use standard views and controls to display their content.
是否需要自己繪制UI取決于創(chuàng)建的App類型,很可能只需要使用很少或者不使用繪制代碼。盡管有一些場(chǎng)景必須使用自定義繪制代碼,但是它們的內(nèi)容通常仍然可以用標(biāo)準(zhǔn)視圖和控件顯示。
The use of custom drawing code should be limited to situations where the content you display needs to change dynamically. For example, a drawing app typically needs to use custom drawing code to track the user’s drawing commands, and an arcade-style game may need to update the screen constantly to reflect the changing game environment. In those situations, you should choose an appropriate drawing technology and create a custom view class to handle events and update the display appropriately.
在顯示需要?jiǎng)討B(tài)改變的內(nèi)容時(shí),應(yīng)該盡可能少的使用自定義繪制代碼。這種情況下應(yīng)該選擇合適的繪制技術(shù),并創(chuàng)建一個(gè)自定義view用來(lái)處理事件和更新顯示內(nèi)容。
On the other hand, if the bulk of your app’s interface is fixed, you can render the interface in advance to one or more image files and display those images at runtime using theUIImageViewclass. You can layer image views with other content as needed to build your interface. You can also use theUILabelclass to display configurable text and include buttons or other controls to provide interactivity. For example, an electronic version of a board game can often be created with little or no custom drawing code.
如果你的app需要顯示的內(nèi)容是固定的,你可以預(yù)先將這些內(nèi)容輸入到圖像文件并使用UIImageView來(lái)顯示。
Because custom views are generally more processor-intensive (with less help from the GPU), if you can do what you need to do using standard views, you should always do so. Also, you should make your custom views as small as possible, containing only content that you cannot draw in any other way, use use standard views for everything else. If you need to combine standard UI elements with custom drawing, consider using a Core Animation layer to superimpose a custom view with a standard view so that you draw as little as possible.
因?yàn)樽远x視圖通常是計(jì)算密集型操作,(較少的獲得GPU的協(xié)助),能使用標(biāo)準(zhǔn)視圖的情況下盡量使用標(biāo)準(zhǔn)視圖。盡可能少的使用自定義視圖。如果需要在標(biāo)準(zhǔn)視圖上繪制自定義內(nèi)容,可以考慮使用Core Animation layer疊加在標(biāo)準(zhǔn)視圖上面,這樣就可以較少的使用自定義繪制代碼。
關(guān)鍵概念和理論
For thedrawRect:method, UIKit creates agraphics contextfor rendering to the display. This graphics context contains the information the drawing system needs to perform drawing commands, including attributes such as fill and stroke color, the font, the clipping area, and line width. You can also create and draw into custom graphics context for bitmap images and PDF content.
UIKit創(chuàng)建一個(gè)圖形上下文(graphics context)用于呈現(xiàn)內(nèi)容,graphics context包括繪制系統(tǒng)執(zhí)行繪制命令的信息,包括填充屬性、繪制顏色、字體、剪切區(qū)域、線寬等等。你也可以在自定義圖形上下文創(chuàng)建和繪制位圖及PDF。
UIKit has adefault coordinate systemwhere the origin of drawing is at the top-left of a view; positive values extend downward and to the right of that origin. You can change the size, orientation, and position of the default coordinate system relative to the underlying view or window by modifying the current transformation matrix, which maps a view’s coordinate space to the device screen.
UIKit默認(rèn)的坐標(biāo)系統(tǒng),起點(diǎn)是左上角
In iOS, thelogical coordinate space, which measures distances in points, is not equal to the device coordinate space, which measures in pixels. For greater precision, points are expressed in floating-point values.
邏輯坐標(biāo)空間是以點(diǎn)為單位的,不同于設(shè)備以像素為單位的坐標(biāo)系統(tǒng)。為了更大的精確度,點(diǎn)坐標(biāo)用浮點(diǎn)數(shù)表示。
iOS Drawing Concepts
Important:Not all UIKit classes are thread safe. Be sure to check the documentation before performing drawing-related operations on threads other than your app’s main thread.
The UIKit Graphics System
所有繪制都是在UIView和它的子類中。UIView定義了繪制發(fā)生在屏幕的哪一個(gè)部分(確定繪制區(qū)域)。如果用系統(tǒng)提供的View,繪制區(qū)域這個(gè)已經(jīng)自動(dòng)處理好了。
離屏繪制位圖或者PDF上下文時(shí),并不是在一個(gè)UIView中繪制,也就意味著關(guān)于繪制的部分概念是不適用的,例如The View Drawing Cycle。
The View Drawing Cycle
當(dāng)view第一次顯示或者view的某個(gè)區(qū)域需要重新繪制時(shí),回調(diào)用view的drawRect:方法
以下幾種情況會(huì)觸發(fā)view更新:
1、移入/移除一個(gè)view遮蓋住當(dāng)前view
2、一個(gè)預(yù)先隱藏的view,設(shè)置器hidden屬性為NO
3、把一個(gè)離屏的view又回到屏幕
4、在view中顯示的調(diào)用setNeedsDisplayorsetNeedsDisplayInRect:方法
系統(tǒng)View是自動(dòng)管理重繪的。
自定義View,需要重寫drawRect:方法,并在這個(gè)方法內(nèi)執(zhí)行所有的繪制代碼。
The first time your view becomes visible, iOS passes a rectangle to the view’sdrawRect:method that contains your view’s entire visible area.
當(dāng)自定義View第一次變得可見時(shí),iOS會(huì)發(fā)送一個(gè)矩形給View的drawRect:方法,這個(gè)矩形包括View所有的可見區(qū)域。
During subsequent calls, the rectangle includes only the portion of the view that actually needs to be redrawn.
在之后的調(diào)用中,這個(gè)矩形只包含實(shí)際重繪的區(qū)域。
如果希望刷新View的內(nèi)容,調(diào)用setNeedsDisplayorsetNeedsDisplayInRect:方法觸發(fā)重繪。
不要自行調(diào)用drawRect:方法,這個(gè)方法只能由系統(tǒng)再次繪制的代碼自動(dòng)調(diào)用。因?yàn)樵谄渌臅r(shí)候,并不存在圖形上下文,所以不能繪制。
Coordinate Systems and Drawing in iOS
The drawing (user) coordinate system. This coordinate system is used when you issue drawing commands.
The view coordinate system (base space). This coordinate system is a fixed coordinate system relative to the view.
The (physical) device coordinate system. This coordinate system represents pixels on the physical screen.
Each view also has acurrent transformation matrix (CTM), a mathematical matrix that maps the points in the current drawing coordinate system to the (fixed) view coordinate system. The app can modify this matrix (as described later) to change the behavior of future drawing operations.
An upper-left-origin coordinate system (ULO),The default coordinate system used by the UIKit and Core Animation frameworks is ULO-based.默認(rèn)坐標(biāo)系統(tǒng)
A lower-left-origin coordinate system (LLO),Core Graphics framework is LLO-based
Before calling your view’sdrawRect:method, UIKit establishes the default coordinate system for drawing to the screen by making a graphics context available for drawing operations.
Obtaining Graphics Contexts
Most of the time, graphics contexts are configured for you. Each view object automatically creates a graphics context so that your code can start drawing immediately as soon as your customdrawRect:method is called. As part of this configuration, the underlyingUIViewclass creates a graphics context (aCGContextRefopaque type) for the current drawing environment.
大多數(shù)時(shí)候,圖形上下文已經(jīng)給你配置好了。每一個(gè)UIView對(duì)象會(huì)自動(dòng)創(chuàng)建一個(gè)圖形上下文對(duì)象,因此你可以在調(diào)用drawRect:后立即開始執(zhí)行自己的自定義繪制。UIView隱式的為當(dāng)前繪制環(huán)境創(chuàng)建了一個(gè)CGContextRef類型的繪制上下文對(duì)象。
If you want to draw somewhere other than your view (for example, to capture a series of drawing operations in a PDF or bitmap file), or if you need to call Core Graphics functions that require a context object, you must take additional steps to obtain a graphics context object. The sections below explain how.
如果需要繪制除了當(dāng)前View以外其他的東西(例如,在位圖或者PDF里面獲取一系列的繪制操作),或者需要一個(gè)上下文對(duì)象來(lái)調(diào)用Core Graphics函數(shù),那么你必須用其他的步驟去獲取一個(gè)圖形上下文對(duì)象。
Drawing to the Screen
如果使用Core Graphics函數(shù)在UIKit的view中繪制圖形,你的繪制操作應(yīng)該使用ULO坐標(biāo)系統(tǒng)。
UIGraphicsGetCurrentContext可以獲取當(dāng)前繪制環(huán)境的CGContextRef對(duì)象。
如果你創(chuàng)建了一個(gè)PDF上下文,那么UIGraphicsGetCurrentContext會(huì)返回該P(yáng)DF的CGContextRef對(duì)象。如果你要把它繪制到View,必須使用UIGraphicsGetCurrentContext返回的這個(gè)CGContextRef對(duì)象。
Drawing to Bitmap Contexts and PDF Contexts
Both the bitmap context and the PDF context provided by UIKit establish a ULO default coordinate system.The context that an app directly creates through Core Graphics, however, establishes a LLO default coordinate system.
bitmap上下文和PDF上下文是基于ULO坐標(biāo)系統(tǒng)的。如果直接用Core Graphics的函數(shù)創(chuàng)建一個(gè)context,則是基于LLO坐標(biāo)系統(tǒng)的。
Color and Color Spaces
UIColor對(duì)象提供了方便的方法指定顏色,不需要自己指定顏色空間,它已經(jīng)被UIColor對(duì)象自動(dòng)指定了。
也可以使用CGContextSetRGBStrokeColorandCGContextSetRGBFillColor創(chuàng)建和設(shè)置顏色,盡管Core Graphics支持使用其他的顏色空間創(chuàng)建顏色或者自定義顏色空間,但不推薦在自定義繪制代碼中使用,自定義繪制應(yīng)該一直使用RGB色彩空間。
Configuring the Graphics Context
上下文狀態(tài)可以保存,使用CGContextSaveGState保存一個(gè)上下文狀態(tài),將狀態(tài)推入堆中。接下來(lái)對(duì)上下文狀態(tài)的操作不會(huì)影響保存到堆中的上下文狀態(tài)。當(dāng)需要恢復(fù)到之前的上下文狀態(tài)時(shí),可以使用CGContextRestoreGState恢復(fù)。這樣在不同的上下文狀態(tài)之間切換就不用重復(fù)執(zhí)行配置代碼。
Customizing the Coordinate Space
you can change the CTM by adding scaling, rotation, and translation factors to it and thereby change the size, orientation, and position of the default coordinate system relative to the underlying view or window.
Using Coordinate Transforms to Improve Drawing Performance