View Architecture Fundamentals
一、視圖架構基礎
Most of the things you might want to do visually are donewith view objects—instances of the?UIView?class.A view object defines a rectangular region on the screen and handles thedrawing and touch events in that region. A view can also act as a parent forother views and coordinate the placement and sizing of those views. TheUIViewclass does most of thework in managing these relationships between views, but you can also customizethe default behavior as needed.
大多數你可能想要做的可視化是由視圖對象完成的——及UIView類的實例。視圖對象在屏幕上定義了一個矩形區域,并在該區域內處理繪圖和觸摸事件。視圖也可以充當其它視圖的父視圖,并為那些視圖定位和定尺寸。UIView類的大部分工作是管理這些視圖間關系,你也可以根據需要自定義默認行為。
Views work in conjunction with Core Animation layers tohandle the rendering and animating of a view’s content.Every view in UIKit is backed by a layer object (usually an instance of?theCALayerclass), which?manages the backing store for the view and handles view-related animations.Mostoperations you perform should be through theUIViewinterface. However, insituations where you need more control over the rendering or animation behaviorof your view, you can perform operations through its layer instead.
視圖結合內核動畫(Core Animation)層一起,來處理視圖內容的渲染和動畫。通過一個層對象(通常是CALayer類的一個實例),在UIKit框架里的每個視圖都支持管理視圖的后臺存儲和處理視圖相關的各種動畫。你執行的大多數操作應該憑借UIView接口。然而,在你需要更多的控制關于渲染(rendering)或動畫視圖的行為的情況下,你可以執行操作它的層來代替。
To understand the relationship between views and layers, ithelps to look at an example.Figure 1-1showsthe view architecture from the?ViewTransitions?sample application along withthe relationship to the underlying Core Animation layers. The views in theapplication include a window (which is also a view), a genericUIViewobject that acts as acontainer view, an image view, a toolbar for displaying controls, and a barbutton item (which is not a view itself but which manages a view internally).(The actual?ViewTransitions?sample application includes anadditional image view that is used to implement transitions. For simplicity,and because that view is usually hidden, it is not included inFigure 1-1.) Every view has a corresponding layerobject that can be accessed from that view’s?layer?property.(Because a bar button item is not a view, you cannot access its layerdirectly.) Behind those layer objects are Core Animation rendering objects andultimately the hardware buffers used to manage the actual bits on the screen.
為了理解視圖和層之間的關系,看個例子更有幫助。圖1-1顯示了ViewTransitions示例應用中的視圖結構,以及跟底層的內核動畫層之間的關系。應用中的視圖包含一個窗口(也是一個視圖),一個通用的UIView對象,它充當容器視圖(container view),一個圖像視圖,用于顯示控件的工具欄,和一個工具欄按鈕項(它本身不是一個視圖,但是在內部管理了一個視圖)。(實際的ViewTransitions示例應用還包含一個額外的圖像視圖,用來實現過渡(transitions)。因為那個視圖通常是隱藏的,為簡單起見沒包含在圖1-1里)每一個視圖都有一個對應的層對象,可以從該視圖的layer屬性訪問。(因為工具欄按鈕項不是一個視圖,你不能直接訪問它的層)這些層對象的背后是內核動畫渲染對象,最終硬件緩存(hardware?buffers)用來管理屏幕上的實際位。
Figure 1-1Architecture?of the views in a sample application
The use of Core Animation layer objects has importantimplications for performance. The actual drawing code of a view object iscalled as little as possible, and when the code is called, the results arecached by Core Animation and reused as much as possible later. Reusingalready-rendered content eliminates the expensive drawing cycle usually neededto update views.Reuse of this content is especially?important during animations, where the existing content can be manipulated.Suchreuse is much less expensive than creating new content.
內核動畫層對象的使用對性能有很重要的意義。視圖的對象的實際繪圖代碼會被盡可能少的調用,當代碼被調用時,結果通過內核動畫緩存,并在以后盡可能多的重用。重用已經被渲染的內容減少了通常需要更新視圖的昂貴的繪圖周期。在動畫時這個存在的內容能被操作,而且這個內容的重用是尤其重要的。這樣的重用比創建新內容節省消耗。
View Hierarchies and Subview Management
1.視圖層次以及子視圖管理
In addition to providing its own content, a view can act asa container for other views. When one view contains another, a parent-childrelationship is created between the two views. The child view in therelationship is known as the?subview?and the parent view is known asthe?superview. The creation of this type of relationship has implicationsfor both the visual appearance of your application and the application’s?behavior.
除了提供它自己的內容,視圖還能充當其它視圖的容器。當一個視圖包含了另一個時,在這兩個視圖之間就建立了父子關系。在這個關系中的子視圖通常被稱為子視圖(subview),而父視圖則被稱為superview。這種類型的關系的創建對于你應用的可視化外觀和應用的行為都有一定的影響。
Visually, the content of a subview obscures all or part ofthe content of its parent view. If the subview is totally opaque, then the areaoccupied by the subview completely obscures the corresponding area of theparent. If the subview is partially transparent, the content from the two viewsis blended together prior to being displayed on the screen. Each superviewstores its subviews in an ordered array and the order in that array alsoaffects the visibility of each subview. If two sibling subviews overlap eachother, the one that was added last (or was moved to the end of the subviewarray) appears on top of the other.
在視覺上,子視圖的內容掩蓋了全部或部分它的父視圖的內容。如果子視圖是完全不透明的,則子視圖占據的區域完全掩蓋了父視圖的相應區域。如果子視圖部分透明的,則兩個視圖的內容在顯示到屏幕上之前被混合在一起。每個父視圖把它們的子視圖按照一定順序存在一個數組里,該順序也影響了每個子視圖的可見性。如果兩個兄弟子視圖互相重疊,則后加(或被移到子視圖數組的末尾的)的視圖顯示在前一個視圖的上面。
The superview-subview relationship also impacts severalview behaviors. Changing the size of a parent view has a ripple effect that cancause the size and position of any subviews to change too. When you change thesize of a parent view, you can control the resizing behavior of each subview byconfiguring the view appropriately. Other changes that affect subviews includehiding a superview, changing a superview’s alpha (transparency), or applying amathematical transform to a superview’s coordinate system.
The arrangement of views in a view hierarchy alsodetermines how your application responds to events. When a touch occurs insidea specific view, the system sends an event object with the touch informationdirectly to that view for handling. However, if the view does not handle aparticular touch event, it can pass the event object along to its superview. Ifthe superview does not handle the event, it passes the event object to itssuperview, and so on up the responder chain. Specific views can also pass theevent object to an interveningresponder object,such as a view controller. If no object handles the event, it eventuallyreaches the application object, which generally discards it.
視圖在視圖層次里的排列也決定了應用程序如何對事件做出響應。當觸摸發生在一個特定視圖內部時,系統直接發送一個具有觸摸信息的事件對象讓其處理。然而,如果該視圖沒有處理特定的觸摸事件,它能夠向前傳遞事件對象到它的父視圖。如果它的父視圖還沒有處理該事件,則把事件傳遞給父視圖的父視圖,如此這般逐級提高響應鏈。特定視圖也可以傳遞事件對象給一個介于中間的響應對象,比如一個視圖控制器。如果沒有對象處理該事件,它最終會被傳遞到應用程序對象,通常由應用程序對象把它丟棄。
For more information about how to create view hierarchies,see“Creating?and Managing a View Hierarchy.”
關于如何創建視圖層次的更多信息,請看“Creating?and Managing a View Hierarchy.”
The View Drawing Cycle
2.視圖繪制周期
TheUIViewclassuses an on-demand drawing model for presenting content. When a view firstappears on the screen, the system asks it to draw its content. The systemcaptures a snapshot of this content and uses that snapshot as the view’s visualrepresentation. If you never change the view’s content, the view’s drawing codemay never be called again. The snapshot image is reused for most operationsinvolving the view. If you do change the content, you notify the system thatthe view has changed. The view then repeats the process of drawing the view andcapturing a snapshot of the new results.
UIView類使用一種按需繪制模型(on-demand?drawing model)來呈現視圖內容。當視圖第一次出現在屏幕上時,系統要求它繪制其內容。系統捕捉該內容的快照,并使用該快照作為視圖的視覺呈現(visual?representation)。如果你一點也沒有改變視圖的內容,那視圖的繪制代碼可能不會再被調用。快照圖片被涉及視圖的大多數操作所重用。如果你對內容做了改變,你需要通知系統告訴它視圖已經改變。然后視圖重復繪制視圖過程,并捕捉新的快照。
When the contents of your view change, you do not redrawthose changes directly. Instead, you invalidate the view using either the?setNeedsDisplay?or?setNeedsDisplayInRect:method.These methods tell the system that the contents of the view changed and need tobe redrawn at the next opportunity. The system waits until the end of thecurrent run loop before initiating any drawing operations. This delay gives youa chance to invalidate multiple views, add or remove views from your hierarchy,hide views, resize views, and reposition views all at once. All of the changesyou make are then reflected at the same time.
當你的視圖內容發生改變時,你不會直接重新繪制那些改變。你可以用setNeedsDisplay或setNeedsDisplayInRect:方法讓視圖無效。這些方法告訴系統視圖的內容已經發生改變,需要在下次重新繪制。該系統在啟動任何繪圖操作之前,等待當前運行循環的結束。該延時給你一次機會,用來一次性完成廢棄多個視圖,從視圖層次里添加或刪除視圖,隱藏視圖,調整視圖大小,重新配置視圖等。所有這些你做的變化將在同一時間反映出來。
Note:?Changinga view’s geometry does not automatically cause the system to redraw the view’scontent. The view’scontentModepropertydetermines how changes to the view’s geometry are interpreted. Most contentmodes stretch or reposition the existing snapshot within the view’s boundariesand do not create a new one. For more information about how content modesaffect the drawing cycle of your view, see“Content?Modes.”
注意:改變視圖的幾何結構并不會自動導致系統重畫視圖內容。視圖的contentMode屬性確定了如何改變視圖的幾何解釋。大多數內容模式都是在視圖邊界里拉伸或重新配置已經存在的快照,并不需要創建新視圖內容。了解更多關于內容模式如何影響視圖的繪制周期,請看“Content?Modes.”
When the time comes to render your view’s content, the?actual drawing process varies depending on the view and its configuration.?System views typically implement private drawing methods to render their?content. Those same system views often expose interfaces that you can use to?configure the view’s actual appearance. For customUIViewsubclasses, you typicallyoverride the?drawRect:method of your view and use that method to draw yourview’s content. There are also other ways to provide a view’s content, such assetting the contents of the underlying layer directly, but overriding thedrawRect:method is the mostcommon technique.
當開始渲染視圖內容時,實際的繪圖過程根據視圖和它的配置而變化。系統視圖通常執行私有繪圖方法來渲染它們的內容。那些相同的系統視圖常常暴露出接口,讓你可以用來配置視圖實際的外觀。為了定制UIView子類,你通常重載(override)視圖的drawRect:方法,并用該方法繪制視圖的內容。還有其它方法來提供一個視圖的內容,比如直接設置底層內容,但是重載drawRect:方法是最通用的技術。
For more information about how to draw content for customviews, see“Implementing?Your Drawing Code.”
更多有關如何繪制自定義視圖的內容方面的信息,請看“Implementing?Your Drawing Code.”
Content Modes
3.內容模式
Each view has a content mode that controls how the viewrecycles its content in response to changes in the view’s geometry and whetherit recycles its content at all. When a view is first displayed, it renders itscontent as usual and the results are captured in an underlying bitmap. Afterthat, changes to the view’s geometry do not always cause the bitmap to berecreated. Instead, the value in thecontentModepropertydetermines whether the bitmap should be scaled to fit the new bounds or simplypinned to one corner or edge of the view.
每個視圖都有一個內容模式(content model),在視圖幾何外形發生變化時,用來控制視圖如何回收重用它的內容來響應視圖幾何外形的改變,以及是否回收重用其全部內容。當視圖被第一次顯示時,它跟平時一樣渲染它的內容,并且結果被捕獲到一個底層位圖里。然后,視圖幾何外形的改變并不總是導致重新創建位圖。相反,contentMode屬性的值決定了該位圖是否應該縮放來適應新的邊界,或只需要簡單的固定到視圖的一個角落或一邊。
The content mode of a view is applied whenever you do thefollowing:
視圖的內容模式被應用到以下情況:
? ? ·Change the width or height ofthe view’sframeorboundsrectangles.
? ? 更改視圖框架或矩形邊界(frameorbounds)的長度或寬度。
? ? ·Assign a transform thatincludes a scaling factor to the view’stransformproperty.
? ? 給視圖transform的屬性分配一個變換,該變換包含一個縮放因子。
By default, thecontentModeproperty for most views is set to?UIViewContentModeScaleToFill,which causes the view’s contents to be scaled to fit the new frame size.Figure 1-2shows the results that occur for somecontent modes that are available. As you can see from the figure, not allcontent modes result in the view’s bounds being filled entirely, and those thatdo might distort the view’s content.
默認時,大多數視圖的內容模式屬性被設為UIViewContentModeScaleToFill,該設置導致視圖的內容被縮放以適應新的框架尺寸。圖1-2顯示了一些可用的內容模式效果。正如你在圖中看到,不是所有的內容模式導致視圖邊界被完全填滿,而且那些確實填滿邊界的圖形可能失真(distort)。
Figure 1-2??Content mode comparisons
圖1-2內容模式比較
Content modes are good for recycling the contents of yourview, but you can also set the content mode to the?UIViewContentModeRedraw?valuewhen you specifically want your custom views to redraw themselves duringscaling and resizing operations. Setting your view’s content mode to this valueforces the system to call your view’sdrawRect:method in response to geometry changes. In general, you shouldavoid using this value whenever possible, and you should certainly not use itwith the standard system views.
內容模式對于回收視圖內容很好,但是你也可以設置內容模式為UIViewContentModeRedraw值,當你明確地想要你的自定義視圖在縮放和大小調整操作也重新繪制時。把你的視圖內容模式設置為該值強制系統在視圖幾何外形發生變化時調用drawRect:方法。一般來說,你應該盡可能的避免使用該值,而且確定不把它跟標準系統視圖一起使用。
For more information about the available content modes,see?UIView Class Reference.
更多有關可用內容模式的信息,請看UIView Class Reference.
StretchableViews
4.可拉伸視圖
You can designate a portion of a view as stretchable sothat when the size of the view changes only the content in the stretchableportion is affected. You typically use stretchable areas for buttons orother views where part of the view defines a repeatable?pattern. The stretchable area you specify can allow for stretching alongone or both axes of the view. Of course, when stretching a view along two axes,the edges of the view must also define a repeatable pattern to avoid anydistortion.Figure 1-3?shows how this distortion manifests itself in aview. The color from each of the view’s original pixels is replicated to fillthe corresponding area in the larger view.
你可以指明視圖的一部分為可拉伸的,以便當視圖的大小發生改變時,只有可拉伸部分的內容受到影響。你通常對按鈕,或對定義了一個可重復圖案的視圖的一部分,使用可拉伸區域。你指定的可拉伸區域可以允許在一個或兩個軸方向上拉伸視圖。當然,當視圖沿著兩個軸被拉伸時,視圖邊緣必須也定義一個可重復的圖案,用來避免任何失真。圖1-3顯示了失真的情況。視圖的每個初始像素顏色被復制到了一個更大視圖的相應區域里。
Figure 1-3??Stretching the background of abutton
圖1-3拉伸按鈕的背景
You specify the stretchable area of a view using the?contentStretch?property.This property accepts a rectangle whose values are normalized to therange0.0to1.0. When stretching the view, the?system multiplies these normalized values by the view’s current bounds and?scale factor to determine which pixel or pixels need to be stretched. The use?of normalized values alleviates the need for you to update thecontentStretchproperty everytime the bounds of your view change.
你可以用contentStretch屬性指定視圖的可拉伸區域。這個屬性接受一個矩形,它的值被規范化到0.0至1.0范圍內。當拉伸視圖時,系統用這些規范化的值乘以視圖當前的邊界和縮放因子來決定哪個像素或哪些像素需要被拉伸。標準化值的使用緩解了每次視圖邊界變化時必須更新contentStretch屬性的需求。
The view’s content mode also plays a role in determininghow the view’s stretchable area is used. Stretchable areas are only used whenthe content mode would cause the view’s content to be scaled. This means thatstretchable views are supported only withthe?UIViewContentModeScaleToFill, UIViewContentModeScaleAspectFit, ?and ?UIViewContentModeScaleAspectFill?contentmodes. If you specify a content mode that pins the content to an edge or corner(and thus does not actually scale the content), the view ignores thestretchable area.
視圖內容模式還決定了如何使用視圖的可拉伸區域。可拉伸區域只在內容模式將引起視圖的內容被縮放時使用。這意味著可拉伸視圖只支持UIViewContentModeScaleToFill,UIViewContentModeScaleAspectFit,和UIViewContentModeScaleAspectFill內容模式。如果你指定了一個把內容固定到一邊或一角的內容模式(就是不會拉伸內容),視圖將忽視可拉伸區域。
Note:?The?use of thecontentStretchproperty is recommended over the creation of a?stretchableUIImageobject when specifying the background for a view. Stretchableviews are handled entirely in the Core Animation layer, which typically offersbetter performance.
注意:當為視圖指定背景時,推薦使用contentStretch屬性創建一個可拉伸的UIImage對象。可拉伸視圖全部在內核動畫層里處理,這樣通常提供了更好的性能。
Built-In Animation Support
5.內置動畫支持
One of the benefits of having a layer object behind everyview is that you can animate many view-related changes easily. Animations are auseful way to communicate information to the user and should always beconsidered during the design of your application. Many properties of the?UIView?classare?animatable—that is, semiautomatic support exists for animating fromone value to another. To perform an animation for one of these animatableproperties, all you have to do is:
每個視圖后面都有一個層對象的好處之一是你可以容易地讓許多視圖相關的變換動畫化。動畫是將信息傳遞給用戶的一種很有用的方式,在應用程序設計過程中應該始終被考慮。UIView類的很多屬性都是可動畫的——就是,半自動化支持動畫從一個值到另一個值。為了讓這些可動畫的屬性執行一個動畫,你所要做的是:
? ? 1.Tell UIKit that you want to perform an animation.
? ? 告訴UIKit你想要執行一個動畫。
? ? 2.Change the value of the property.
? ? 改變屬性的值。
Among the properties you can animate on aUIViewobject are the following:
支持動畫的UIView對象屬性包括:
? ? ·frame—Usethis to animate position and size changes for the view.
? ? ??frame—用它讓視圖的位置和尺寸變換發生動畫。
? ? ·bounds—Usethis to animate changes to the size of the view.
? ? ??bounds—用它讓視圖的尺寸變化發生動畫。
? ? ·center—Usethis to animate the position of the view.
? ? ??center—用它讓視圖定位發生動畫。
? ? ·transform—Usethis to rotate or scale the view.
? ? ??transform—用它旋轉或縮放視圖
? ? ·alpha—Usethis to change the transparency of the view.
? ? ??alpha—用它改變視圖的透明度
? ? ·backgroundColor—Usethis to change the background color of the view.
? ? ??backgroundColor—用它改變視圖的背景顏色
? ? ·contentStretch—Usethis to change how the view’s contents stretch.
? ? ??contentStretch—用它改變視圖如何拉伸
One place where animations are very important is whentransitioning from one set of views to another. Typically, you use a viewcontroller to manage the animations associated with major changes between partsof your user interface. For example, for interfaces that involve navigatingfrom higher-level to lower-level information, you typically use a navigationcontroller to manage the transitions between the views displaying eachsuccessive level of data. However, you can also create transitions between twosets of views using animations instead of a view controller. You might do so inplaces where the standard view-controller animations do not yield the resultsyou want.
一個動畫應用很重要的地方是從一個視圖集過渡到另一個視圖集。通常,你使用一個視圖控制器來管理跟用戶界面各部分之間的主要變換有關的動畫。例如,對于接口,包括從高級到低級導航信息,您通常使用導航控制器來管理視圖顯示每個連續的數據之間的轉換。然而,你也可以用動畫來創建兩個視圖集之間的過渡,而不用視圖控制器。當標準試圖控制動畫不能得到你想要的效果時,你可能會這樣做。
In addition to the animations you create using UIKitclasses, you can also create animations using Core Animation layers. Droppingdown to the layer level gives you much more control over the timing andproperties of your animations.
除了用UIKit類來創建動畫,你還可以用內核動畫層來創建動畫。下降到層級別讓你控制更多的動畫時機和屬性。
For details about how to perform view-based animations,see“Animations.”Formore information about creating animations using Core Animation, see?Core Animation Programming Guide?and?Core Animation Cookbook.
有關如何執行基于視圖的動畫的更多詳情,請看“Animations.”更多關于用內核動畫創建動畫的信息,請看Core Animation Programming Guide和Core Animation Cookbook.