視圖和窗口架構html
Views and windows present your application’s user interface and handle the interactions with that interface. UIKit and other system frameworks provide a number of views that you can use as-is with little or no modification. You can also define custom views for places where you need to present content differently than the standard views allow.react
視圖和窗口表現了應用程序的用戶界面,並處理與該界面的各類交互。 UIKit 和其它系統框架提供了不少你能夠不修改或作不多修改就能直接使用的各類視圖。若是標準視圖所表示的內容不符合你的需求,你也能夠自定義視圖。ios
Whether you use the system views or create your own custom views, you need to understand the infrastructure provided by the UIView
and UIWindow
classes. These classes provide sophisticated facilities for managing the layout and presentation of views. Understanding how those facilities work is important for making sure your views behave appropriately when changes occur in your application.express
不管你是使用系統視圖仍是本身建立自定義視圖,你都須要理解UIView 類 和UIWindow類提供的基礎設施。編程
視圖架構基礎windows
Most of the things you might want to do visually are done with view objects—instances of the UIView
class. A view object defines a rectangular region on the screen and handles the drawing and touch events in that region. A view can also act as a parent for other views and coordinate the placement and sizing of those views. The UIView
class does most of the work in managing these relationships between views, but you can also customize the default behavior as needed.數組
大多數你可能想要可視化的事情都是由視圖對象完成的---這些視圖對象都是UIView 類的實例。視圖對象在屏幕上定義了一個矩形區域,並在該區域內處理繪製和觸摸事件。 視圖也能夠做爲其它視圖的父視圖,併爲那些視圖定位和定尺寸。 UIView類負責管理這些視圖間關係的大多數工做, 可是若是須要,你也能夠定製默認行爲。
緩存
Views work in conjunction with Core Animation layers to handle the rendering and animating of a view’s content. Every view in UIKit is backed by a layer object (usually an instance of the CALayer
class), which manages the backing store for the view and handles view-related animations. Most operations you perform should be through the UIView
interface. However, in situations where you need more control over the rendering or animation behavior of your view, you can perform operations through its layer instead.架構
視圖跟內核動畫(Core Animation)層鏈接來處理渲染(模型到圖像)或動畫視圖的內容。 UIKit框架裏的每一個視圖的背後都是一個層對象(一般是CALayer類的一個實例),層對象管理視圖的後臺存儲,並處理視圖相關的各類動畫。 你執行的大多數操做都通過UIView接口。 然而,在你須要更多的控制,不止渲染或動畫視圖的行爲時,你能夠經過它的層代替視圖執行操做。app
To understand the relationship between views and layers, it helps to look at an example. Figure 1-1 shows the view architecture from the ViewTransitions sample application along with the relationship to the underlying Core Animation layers. The views in the application include a window (which is also a view), a generic UIView
object that acts as a container view, an image view, a toolbar for displaying controls, and a bar button item (which is not a view itself but which manages a view internally). (The actual ViewTransitions sample application includes an additional image view that is used to implement transitions. For simplicity, and because that view is usually hidden, it is not included in Figure 1-1.) Every view has a corresponding layer object that can be accessed from that view’s layer
property. (Because a bar button item is not a view, you cannot access its layer directly.) Behind those layer objects are Core Animation rendering objects and ultimately the hardware buffers used to manage the actual bits on the screen.
爲了理解視圖和層之間的關係,看例子比較直觀。 圖1-1 顯示了ViewTransitions 例程應用中的視圖結構,以及跟下面的內核動畫層之間的關係。應用程序中的視圖包含一個窗口(也是一個視圖), 一個通用UIView對象,它做爲一個容器視圖(container view), 一個圖片視圖, 一個工具欄,用來顯示控制鍵, 以及一個工具欄上的按鈕項(自己不是一個視圖,可是在內部管理了一個視圖)。(真正的ViewTransitions 例程應用還包含一個額外的圖片視圖,用來實現變換。 爲了方便,由於那個視圖一般是被隱藏的,因此沒在圖1-1裏包含) 每一個視圖都對應着一個層對象,該層對象能從視圖的layer 屬性被訪問。(由於欄按鈕項不是一個視圖,你不能直接訪問它的層) 那些層對象後面是內核動畫渲染對象,最後硬件緩衝(hardware buffers)管理屏幕上的實際位(bits)。
Figure 1-1 Architecture of the views in a sample application
The use of Core Animation layer objects has important implications for performance. The actual drawing code of a view object is called as little as possible, and when the code is called, the results are cached by Core Animation and reused as much as possible later. Reusing already-rendered content eliminates the expensive drawing cycle usually needed to update views. Reuse of this content is especially important during animations, where the existing content can be manipulated. Such reuse is much less expensive than creating new content.
內核動畫層對象的使用對性能(performance)有很重要的意義。 視圖的對象的真實繪圖代碼會被儘量少的調用,當代碼被調用了以後,結果被緩存在內核動畫,並在之後儘量多的重複使用。 重用已經被渲染的內容消除了視圖更新所須要的昂貴繪圖週期。動畫時重用這些已經存在的內容尤爲重要。 這樣的重用比建立新內容節省消耗。
視圖層次以及子視圖管理
In addition to providing its own content, a view can act as a container for other views. When one view contains another, a parent-child relationship is created between the two views. The child view in the relationship is known as the subview and the parent view is known as the superview. The creation of this type of relationship has implications for both the visual appearance of your application and the application’s behavior.
除了提供它本身的內容,視圖還能做爲其它視圖的容器。當一個視圖容納了另外一個視圖,那麼這2個視圖之間就創建了父子關係。 關係中的子視圖一般被稱爲子視圖(subview),而父視圖則被稱爲superview。這種關係的創建對應用程序的可見外觀以及它的行爲都頗有意義。
Visually, the content of a subview obscures all or part of the content of its parent view. If the subview is totally opaque, then the area occupied by the subview completely obscures the corresponding area of the parent. If the subview is partially transparent, the content from the two views is blended together prior to being displayed on the screen. Each superview stores its subviews in an ordered array and the order in that array also affects the visibility of each subview. If two sibling subviews overlap each other, the one that was added last (or was moved to the end of the subview array) appears on top of the other.
外表上,子視圖的內容包含了父視圖內容的所有或一部分。 若是子視圖是徹底不透明的,則它徹底佔據了父視圖的相應區域。 若是子視圖部分透明,則兩個視圖的內容在屏幕上會被重疊顯示。每一個父視圖把它們的子視圖按照必定順序存在一個數組裏,該順序也影響了每一個子視圖的可見性。 若是2個兄弟子視圖重疊在一塊兒,則後加(或被移到子視圖數組的末尾的)的視圖在前一個視圖的上面。
The superview-subview relationship also impacts several view behaviors. Changing the size of a parent view has a ripple effect that can cause the size and position of any subviews to change too. When you change the size of a parent view, you can control the resizing behavior of each subview by configuring the view appropriately. Other changes that affect subviews include hiding a superview, changing a superview’s alpha (transparency), or applying a mathematical transform to a superview’s coordinate system.
父子視圖關係還影響了一些視圖行爲。 改變父視圖的大小,同時也將讓子視圖的尺寸和位置發生改變。 當你改變父視圖的尺寸時,你能夠經過適當的配置視圖來控制每一個子視圖的大小調整行爲(resizing behavior)。 其它影響子視圖的變化還有隱藏父視圖,改變父視圖的透明度,或給父視圖的定位系統應用一個數學變換。
The arrangement of views in a view hierarchy also determines how your application responds to events. When a touch occurs inside a specific view, the system sends an event object with the touch information directly to that view for handling. However, if the view does not handle a particular touch event, it can pass the event object along to its superview. If the superview does not handle the event, it passes the event object to its superview, and so on up the responder chain. Specific views can also pass the event object to an intervening responder object, such as a view controller. If no object handles the event, it eventually reaches 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 UIView
class uses an on-demand drawing model for presenting content. When a view first appears on the screen, the system asks it to draw its content. The system captures a snapshot of this content and uses that snapshot as the view’s visual representation. If you never change the view’s content, the view’s drawing code may never be called again. The snapshot image is reused for most operations involving the view. If you do change the content, you notify the system that the view has changed. The view then repeats the process of drawing the view and capturing a snapshot of the new results.
UIView 類使用一個按需繪製模型(on-demand drawing model)來呈現視圖內容。 當視圖第一次出如今屏幕上時,系統要求它繪製其內容。 系統捕捉該內容的快照,並使用該快照做爲視圖的視覺代理(visual representation)。 若是你歷來沒有改變視圖的內容,那視圖的繪製代碼可能永遠也不會再被調用。快照圖片被視圖設計的大多數操做所重用。若是你對內容作了改變,你須要通知系統告訴它視圖已經改變。 而後視圖重複繪製視圖過程,從新捕捉新的快照。
When the contents of your view change, you do not redraw those 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 to be redrawn at the next opportunity. The system waits until the end of the current run loop before initiating any drawing operations. This delay gives you a 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 changes you make are then reflected at the same time.
當視圖內容發生改變時,你不會直接從新繪製那些改變。你能夠用 setNeedsDisplay
或 setNeedsDisplayInRect: 方法讓視圖無效。 這些方法告訴系統視圖的內容已經發生改變,須要在下次從新繪製。 系統在直到當前運行循環(current run loop)結束,在任何繪製操做初始化以前一直等待。 該等待給你一次機會,用來無效多個視圖,添加或從視圖層次裏刪除視圖,隱藏視圖,調整視圖大小,一次性從新定位全部視圖等。全部這些你作的變化將在同一時間反映。
Note: Changing a view’s geometry does not automatically cause the system to redraw the view’s content. The view’scontentMode
property determines how changes to the view’s geometry are interpreted. Most content modes stretch or reposition the existing snapshot within the view’s boundaries and do not create a new one. For more information about how content modes affect 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 custom UIView
subclasses, you typically override the drawRect:
method of your view and use that method to draw your view’s content. There are also other ways to provide a view’s content, such as setting the contents of the underlying layer directly, but overriding thedrawRect:
method is the most common technique.
當開始渲染視圖內容時,實際繪圖進程變化取決於視圖和它的配置。 系統視圖一般實現似有繪圖方法來渲染它們的內容。 那些相同的系統視圖經常暴露出你能夠用來配置視圖真實外觀的接口。好比定製UIView 子類,你一般重載視圖的drawRect: 方法,並用該方法繪製視圖的內容。還有其它方法來提供一個視圖的內容,好比直接設置下面的層內容,可是重載 drawRect: 方法是最通用的技術。
For more information about how to draw content for custom views, see 「Implementing Your Drawing Code.」
更多有關若是繪製自定義視圖的內容方面的信息,請看 「Implementing Your Drawing Code.」
Each view has a content mode that controls how the view recycles its content in response to changes in the view’s geometry and whether it recycles its content at all. When a view is first displayed, it renders its content as usual and the results are captured in an underlying bitmap. After that, changes to the view’s geometry do not always cause the bitmap to be recreated. Instead, the value in the contentMode
property determines whether the bitmap should be scaled to fit the new bounds or simply pinned to one corner or edge of the view.
每一個視圖都有一個內容模式,在視圖幾何外形發生變化時,用來控制視圖如何回收它的內容來響應視圖幾何外形的改變,以及是否回收其所有內容。 當視圖被第一次顯示時,它跟平時同樣渲染它的內容,結果被捕捉到一個基本的位圖裏。接着,視圖幾何外形的改變並不老是致使從新建立位圖。相反,contentMode 屬性的值決定了該位圖是否應該縮放來適應新的要求,或只須要簡單的固定到視圖的一個角落或一邊。
The content mode of a view is applied whenever you do the following:
視圖的內容模式被應用到如下狀況:
Change the width or height of the view’s frame
or bounds
rectangles.
Assign a transform that includes a scaling factor to the view’s transform
property.
給視圖transform的屬性分配一個變換,該變換包含一個縮放因子。
By default, the contentMode
property for most views is set to UIViewContentModeScaleToFill
, which causes the view’s contents to be scaled to fit the new frame size. Figure 1-2 shows the results that occur for some content modes that are available. As you can see from the figure, not all content modes result in the view’s bounds being filled entirely, and those that do might distort the view’s content.
默認時, 大多數視圖的內容模式(contentMode)屬性被設爲UIViewContentModeScaleToFill,該設置致使視圖的內容被縮放以適應新的框架尺寸。 圖1-2顯示了一些可用的內容模式效果。正如你在圖中看到,不是全部的內容模式致使視圖邊界被徹底填滿, 那些確實填滿邊界的圖形可能失真(distort)。
Figure 1-2 Content mode comparisons
圖 1-2 內容模式比較
Content modes are good for recycling the contents of your view, but you can also set the content mode to theUIViewContentModeRedraw
value when you specifically want your custom views to redraw themselves during scaling and resizing operations. Setting your view’s content mode to this value forces the system to call your view’s drawRect:
method in response to geometry changes. In general, you should avoid using this value whenever possible, and you should certainly not use it with the standard system views.
內容模式對於回收視圖內容很好,可是你也能夠設置內容模式爲 UIViewContentModeRedraw 值,若是你特別想要你的自定義視圖在縮放和大小調整操做時也從新繪製時。把你的視圖內容模式設置爲該值強制系統在視圖幾何外形發生變化時調用 drawRect: 方法。 通常來講,你應該儘量的避免使用該值,並且肯定不把它跟標準系統視圖一塊兒使用。
For more information about the available content modes, see UIView Class Reference.
更多有關可用內容模式的信息,請看 UIView Class Reference.
可拉伸視圖
You can designate a portion of a view as stretchable so that when the size of the view changes only the content in the stretchable portion is affected. You typically use stretchable areas for buttons or other views where part of the view defines a repeatable pattern. The stretchable area you specify can allow for stretching along one 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 any distortion.Figure 1-3 shows how this distortion manifests itself in a view. The color from each of the view’s original pixels is replicated to fill the corresponding area in the larger view.
你能夠設計視圖的一部分爲可拉伸的,這樣當視圖的大小發生改變時,只有可拉伸部分的內容受到影響。 一般在按鈕或有部分視圖定義了一個可重複圖案的其它視圖裏使用可拉伸區域。你指定的可拉伸區域能夠容許在一個或兩個軸方向上拉伸視圖。 固然,當視圖沿着2個軸被拉伸時,視圖邊緣必須也定義一個可重複的圖案,用來避免任何失真。 圖1-3 顯示了失真的狀況。 視圖的每一個初始像素顏色被複制到了一個更大視圖的相應區域裏。
Figure 1-3 Stretching the background of a button
圖 1-3 拉伸按鈕的背景
You specify the stretchable area of a view using the contentStretch
property. This property accepts a rectangle whose values are normalized to the range 0.0
to 1.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 the contentStretch
property every time the bounds of your view change.
你能夠用contentStretch 屬性指定視圖的可拉伸區域。 該屬性接受一個0.0 到1.0之間的正常值。當拉伸視圖時,系統用這些正常值乘以視圖的當前範圍和縮放因子來決定哪一個像素或哪些像素須要被拉伸。 標準化值的使用緩解了每次視圖邊界變化時必須更新contentStretch屬性的需求。
The view’s content mode also plays a role in determining how the view’s stretchable area is used. Stretchable areas are only used when the content mode would cause the view’s content to be scaled. This means that stretchable views are supported only with the UIViewContentModeScaleToFill
, UIViewContentModeScaleAspectFit
, andUIViewContentModeScaleAspectFill
content modes. 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 the stretchable area.
視圖內容模式還決定了如何使用視圖的可拉伸區域。 可拉伸區域只在內容模式將致使視圖的內容被縮放時使用。 這意味着可拉伸視圖只支持 UIViewContentModeScaleToFill
, UIViewContentModeScaleAspectFit
, 和 UIViewContentModeScaleAspectFill 內容模式。若是你指定了一個把內容固定到一邊或一角的內容模式(就是不會拉伸內容),視圖將忽視可拉伸區域。
Note: The use of the contentStretch
property is recommended over the creation of a stretchable UIImage
object when specifying the background for a view. Stretchable views are handled entirely in the Core Animation layer, which typically offers better performance.
注意:contentStretch 屬性在建立一個可拉伸 UIImage 對象,指定視圖的背景時推薦使用。可拉伸視圖所有在內核動畫層裏處理,內核動畫層一般提供了更好的性能。
內置動畫支持
One of the benefits of having a layer object behind every view is that you can animate many view-related changes easily. Animations are a useful way to communicate information to the user and should always be considered during the design of your application. Many properties of the UIView
class are animatable—that is, semiautomatic support exists for animating from one value to another. To perform an animation for one of these animatable properties, all you have to do is:
每一個視圖後面都有一個層對象的好處之一是你能夠簡單的讓幾個視圖相關的變化經過動畫完成。 動畫是將信息傳遞給用戶的一種頗有用的方式,在應用程序設計過程當中應該始終被考慮。UIView 類的不少屬性都是可動畫的---就是,半自動化支持動畫從一個值到另外一個值。 爲了讓這些屬性執行一個動畫,你只須要作:
Tell UIKit that you want to perform an animation.
告訴UIKit 你想要執行一個動畫。
Change the value of the property.
改變屬性的值。
Among the properties you can animate on a UIView
object are the following:
支持動畫的UIView 對象屬性包括:
frame
—Use this to animate position and size changes for the view.
frame
—用它讓視圖的位置和尺寸變換髮生動畫
bounds
—Use this to animate changes to the size of the view.
bounds
—用它讓視圖的尺寸變化發生動畫
center
—Use this to animate the position of the view.
center
— 用它定位視圖
transform
—Use this to rotate or scale the view.
transform
— 用它旋轉或縮放視圖
alpha
—Use this to change the transparency of the view.
alpha
— 用它改變視圖的透明度
backgroundColor
—Use this to change the background color of the view.
backgroundColor
— 用它改變視圖的背景顏色
contentStretch
—Use this to change how the view’s contents stretch.
contentStretch— 用它改變視圖如何拉伸
One place where animations are very important is when transitioning from one set of views to another. Typically, you use a view controller to manage the animations associated with major changes between parts of your user interface. For example, for interfaces that involve navigating from higher-level to lower-level information, you typically use a navigation controller to manage the transitions between the views displaying each successive level of data. However, you can also create transitions between two sets of views using animations instead of a view controller. You might do so in places where the standard view-controller animations do not yield the results you want.
一個動畫應用很重要的地方是從一個視圖集過渡到另外一個視圖集。一般,你使用一個視圖控制器來管理跟用戶界面各部分之間的主要變換有關的動畫。好比,涉及從高級別信息導航到低級別信息的界面時,你一般會使用一個導航控制器來管理顯示每一個連續級別數據的視圖之間的過渡。然而,你也能夠用動畫來建立2個視圖集之間的過渡,而不用視圖控制器。 當標準試圖控制動畫不能獲得你想要的效果時,你可能會這樣作。
In addition to the animations you create using UIKit classes, you can also create animations using Core Animation layers. Dropping down to the layer level gives you much more control over the timing and properties of your animations.
除了用UIKit類來建立動畫,你還能夠用內核動畫層來建立動畫。 降低到層級別讓你控制更多的動畫時機和屬性。
For details about how to perform view-based animations, see 「Animations.」 For more information about creating animations using Core Animation, see Core Animation Programming Guide and Core Animation Cookbook.
有關如何執行基於視圖的動畫的更多詳情,請看「Animations.」 更多關於用內核動畫建立動畫的信息,請看Core Animation Programming Guide 和 Core Animation Cookbook.
視圖的幾何和座標系統
The default coordinate system in UIKit has its origin in the top-left corner and has axes that extend down and to the right from the origin point. Coordinate values are represented using floating-point numbers, which allow for precise layout and positioning of content regardless of the underlying screen resolution. Figure 1-4 shows this coordinate system relative to the screen. In addition to the screen coordinate system, windows and views define their own local coordinate systems that allow you to specify coordinates relative to the view or window origin instead of relative to the screen.
UIKit 框架的默認座標系統的原點是在左上角, 並有從原點開始向下和向右的座標軸。座標值由浮點-點數字表示,它被用於精確的佈局和內容的定位,不需管底層的屏幕分辨率。 圖1-4 顯示了相對於屏幕的該座標系統。 除了屏幕座標系統,窗口和視圖還定義了它們本身的本地座標系統,用來讓你指定座標,該座標相對於視圖或窗口原點的,而不是相對於屏幕的座標。
Figure 1-4 Coordinate system orientation in UIKit
圖1-4 UIKit 框架的座標系統。
Because every view and window defines its own local coordinate system, you need to be aware of which coordinate system is in effect at any given time. Every time you draw into a view or change its geometry, you do so relative to some coordinate system. In the case of drawing, you specify coordinates relative to the view’s own coordinate system. In the case of geometry changes, you specify coordinates relative to the superview’s coordinate system. The UIWindow
and UIView
classes both include methods to help you convert from one coordinate system to another.
由於每一個視圖和窗口都定義了本身的本地座標系統,你須要在任什麼時候候都意識到是哪一個座標系統在起做用。每次當你繪製一個視圖或改變它的幾何外形時,你都將根據一些座標系統來作定位。 在繪圖時,你指定跟視圖自己的座標系統相關的座標。 在幾何外形發生變化時,你指定跟父視圖的座標系統有關的座標。UIWindow 和 UIView 類都包含了各類幫助你轉換座標系統的方法。
Important: Some iOS technologies define default coordinate systems whose origin point and orientation differ from those used by UIKit. For example, Core Graphics and OpenGL ES use a coordinate system whose origin lies in the lower-left corner of the view or window and whose y-axis points upward relative to the screen. Your code must take such differences into account when drawing or creating content and adjust coordinate values (or the default orientation of the coordinate system) as needed.
重要: 一些iOS 技術定義了默認座標系統,它們的原點和座標軸方向都跟UIKit框架不一樣。 好比, Core Graphics 和 OpenGL ES 的座標系統原點位於視圖或窗口的左下角,y軸向上延伸。 你的代碼在繪圖或建立內容時必須計算到這些區別,並根據須要調整座標值(或座標系統的默認方向)。
Frame, Bounds, Center屬性之間的關係
A view object tracks its size and location using its frame
, bounds
, and center
properties:
視圖對象用frame, bounds, 和 center 屬性監測它的尺寸和位置。
The frame
property contains the frame rectangle, which specifies the size and location of the view in its superview’s coordinate system.
frame 屬性包含了框架矩形, 它指定了視圖的尺寸和以及它在父視圖座標系統中的位置。
The bounds
property contains the bounds rectangle, which specifies the size of the view (and its content origin) in the view’s own local coordinate system.
bounds 屬性包含了邊界矩形, 它指定了視圖在它本身的座標系統中的的尺寸(以及它的初始內容)。
The center
property contains the known center point of the view in the superview’s coordinate system.
center 屬性 包含了已知的視圖中心點,該中心點以父視圖座標系統爲參考。
You use the center
and frame
properties primarily for manipulating the geometry of the current view. For example, you use these properties when building your view hierarchy or changing the position or size of a view at runtime. If you are changing only the position of the view (and not its size), the center
property is the preferred way to do so. The value in thecenter
property is always valid, even if scaling or rotation factors have been added to the view’s transform. The same is not true for the value in the frame
property, which is considered invalid if the view’s transform is not equal to the identity transform.
你主要使用center 和 frame 屬性來操縱當前視圖的幾何外形。 好比, 當你創建視圖層次或在運行時改變視圖的位置或尺寸時使用它們。 若是你只改變視圖的位置,而不改變它的大小,則center屬性是最好的選擇。 center 屬性裏的值永遠都是有效的,即便縮放或旋轉因子已經被添加到視圖的變換(transform)裏。 一樣的狀況下,frame屬性裏的值則不正確,由於該值在視圖的變換不是恆等變換時,被認爲無效。
You use the bounds
property primarily during drawing. The bounds rectangle is expressed in the view’s own local coordinate system. The default origin of this rectangle is (0, 0) and its size matches the size of the frame rectangle. Anything you draw inside this rectangle is part of the view’s visible content. If you change the origin of the bounds rectangle, anything you draw inside the new rectangle becomes part of the view’s visible content.
在繪圖時,bounds 屬性是主要被使用的屬性。 邊界矩形表示在視圖本身的本地座標系統裏。 該矩形的默認原點爲(0,0),而且它的大小跟框架矩形的大小一致。 任何在該矩形裏繪製的東西都是視圖可見內容的一部分。 若是你改變了邊界矩形的原點,任何你在新矩形裏繪製的內容就成爲視圖可見內容的一部分。
Figure 1-5 shows the relationship between the frame and bounds rectangles for an image view. In the figure, the upper-left corner of the image view is located at the point (40, 40) in its superview’s coordinate system and the size of the rectangle is 240 by 380 points. For the bounds rectangle, the origin point is (0, 0) and the size of the rectangle is similarly 240 by 380 points.
圖1-5顯示了一個圖像視圖(image view)的框架矩形(frame rectangle)和邊界矩形(bounds rectangle)之間的關係。在圖中,圖片視圖的左上角座標在它的父視圖座標系裏是點(40,40), 圖片的尺寸是240x380點。 對於邊界矩形來講,原點是(0,0), 矩形大小也是240x380點。
Figure 1-5 Relationship between a view's frame and bounds
圖 1-5 視圖框架和邊框之間的關係
Although you can change the frame
, bounds
, and center
properties independent of the others, changes to one property affect the others in the following ways:
儘管你能夠獨立的改變frame, bounds, 和center屬性, 可是若是你改變了其中一個屬性將對其它屬性形成如下方面的影響:
When you set the frame
property, the size value in the bounds
property changes to match the new size of the frame rectangle. The value in the center
property similarly changes to match the new center point of the frame rectangle.
當你設置frame屬性時,bounds屬性裏的尺寸值將發生變化以匹配框架矩形的新尺寸。 center 屬性的值一樣被改變以匹配框架矩形的新中心點。
When you set the center
property, the origin value in the frame
changes accordingly.
當你設置center屬性時, frame裏的初始值也相應的發生改變。
When you set the size of the bounds
property, the size value in the frame
property changes to match the new size of the bounds rectangle.
當你設置bounds 屬性尺寸時, frame 屬性裏的尺寸也發生改變以匹配邊界矩形的新尺寸。
By default, a view’s frame is not clipped to its superview’s frame. Thus, any subviews that lie outside of their superview’s frame are rendered in their entirety. You can change this behavior, though, by setting the superview’s clipsToBounds
property to YES
. Regardless of whether or not subviews are clipped visually, touch events always respect the bounds rectangle of the target view’s superview. In other words, touch events occurring in a part of a view that lies outside of its superview’s bounds rectangle are not delivered to that view.
默認狀況下, 視圖的框架不會被剪切到它的父視圖框架內。 所以, 任何超出它們父視圖框架的子視圖將所有顯示。 可是,你能夠經過把父視圖的 clipsToBounds 屬性設置爲YES來改變該行爲。無論視覺上子視圖是否被裁減, 視圖永遠只響應它的父視圖範圍內的觸摸事件。換句話說,在父視圖邊界矩形外發生的觸摸事件是不會被傳遞到該視圖的。
座標系轉換
Coordinate system transformations offer a way to alter your view (or its contents) quickly and easily. An affine transform is a mathematical matrix that specifies how points in one coordinate system map to points in a different coordinate system. You can apply affine transforms to your entire view to change the size, location, or orientation of the view relative to its superview. You can also use affine transforms in your drawing code to perform the same types of manipulations to individual pieces of rendered content. How you apply the affine transform therefore depends on context:
座標系轉換讓你快速簡單的變換視圖(或內容)。 反射變換(affine transform)是一種數學矩陣,它指定一個座標系裏的點如何對應於一個不一樣座標系裏的點。 你能夠在整個視圖裏應用反射變換(affine transforms)來改變尺寸,位置或視圖的方向,該方向相對於它父視圖的方向。 你還能夠在你的繪圖代碼裏應用反射變換來對渲染內容的各個獨立塊作一樣類型的操做。所以,根據上下文(context)來決定如何應用反射變換。
To modify your entire view, modify the affine transform in the transform
property of your view.
要想修改整個視圖,修改視圖的transform 屬性中的反射變換。
To modify specific pieces of content in your view’s drawRect:
method, modify the affine transform associated with the active graphics context.
要想修改視圖drawRect: 方法中特定內容塊, 修改跟活動圖形上下文(active graphics context)相關聯的反射變換。
You typically modify the transform
property of a view when you want to implement animations. For example, you could use this property to create an animation of your view rotating around its center point. You would not use this property to make permanent changes to your view, such as modifying its position or size a view within its superview’s coordinate space. For that type of change, you should modify the frame rectangle of your view instead.
當你想實現動畫時,你一般會修改視圖的transform屬性。 好比,你可使用該屬性來建立一個讓視圖圍繞它的中心點旋轉的動畫。 你可能不會使用該值來作視圖的永久變化,好比修改視圖在其父視圖的座標系裏的位置或尺寸。 對於那些變化,你應該用修改視圖的框架矩形來替代。
Note: When modifying the transform
property of your view, all transformations are performed relative to the center point of the view.
注意:當你修改視圖的transform 屬性時,全部的變換都是相對於視圖的中心點來執行的。
In your view’s drawRect:
method, you use affine transforms to position and orient the items you plan to draw. Rather than fix the position of an object at some location in your view, it is simpler to create each object relative to a fixed point, typically (0, 0), and use a transform to position the object immediately prior to drawing. That way, if the position of the object changes in your view, all you have to do is modify the transform, which is much faster and less expensive than recreating the object at its new location. You can retrieve the affine transform associated with a graphics context using theCGContextGetCTM
function and you can use the related Core Graphics functions to set or modify this transform during drawing.
在視圖的drawRect:方法中, 你可使用反射變換來給你想要繪畫的內容作定位和定方向。與其在視圖裏對一個對象作不一樣位置的定位,不如根據一個固定點(一般是(0,0))來建立每一個對象, 並緊接着在繪圖時使用變換(transform)來作對象定位,這樣作更加容易。那樣,若是視圖中的對象位置發生了改變,你只須要修改transform,這樣比在新位置從新建立對象更快更省消耗。你能夠用 CGContextGetCTM 函數來取回跟一個圖形上下文(graphics context)相關聯的反射變換, 並且你能夠在繪圖期間使用相關的內核圖形函數來設置或修改該transform.
The current transformation matrix (CTM) is the affine transform in use at any given time. When manipulating the geometry of your entire view, the CTM is the affine transform stored in your view’s transform
property. Inside yourdrawRect:
method, the CTM is the affine transform associated with the active graphics context.
當前變換矩陣(CTM) 是在任何特定時間正在使用的反射變換。 當操縱整個視圖的幾何外觀時, CTM是存儲在視圖的 transform 屬性裏的反射變換。在drawRect:方法裏, CTM是跟活動圖形上下文相關聯的反射變換。
The coordinate system of each subview builds upon the coordinate systems of its ancestors. So when you modify a view’stransform
property, that change affects the view and all of its subviews. However, these changes affect only the final rendering of the views on the screen. Because each view draws its content and lays out its subviews relative to its own bounds, it can ignore its superview’s transform during drawing and layout.
每一個子視圖的座標系都創建在它先祖的座標系基礎上。 因此當你修改一個視圖的 transform 屬性時, 該改變會影響視圖及它的全部子視圖。 然而,這些改變隻影響最終呈如今屏幕上的視圖。 由於每一個視圖繪製它的內容並根據它本身的邊界佈局它的子視圖,因此它在繪圖和佈局期間能忽略它父視圖的變換(transform)。
Figure 1-6 demonstrates how two different rotation factors combine visually when rendered. Inside the view’s drawRect:
method, applying a 45 degree rotation factor to a shape causes that shape to appear rotated by 45 degrees. Applying a separate 45 degree rotation factor to the view then causes the shape to appear to be rotated by 90 degrees. The shape is still rotated by only 45 degrees relative to the view that drew it, but the view rotation makes it appear to be rotated by more.
圖1-6 顯示了視覺上2個不一樣旋轉因子在渲染時是如何被合併的。在視圖的drawRect:方法,給一個圖形應用一個旋轉45度角的旋轉因子,讓圖形(shape)旋轉45度。而後給視圖應用一個單獨的45度角旋轉因子,圖形看起來就像被旋轉了90度。 而實際上圖形相對於繪製它的視圖來講任然只旋轉了45度, 可是視圖的旋轉讓它看起來旋轉了更多。
Figure 1-6 Rotating a view and its content
圖 1-6 旋轉視圖及它的內容
Important: If a view’s transform
property is not the identity transform, the value of that view’s frame
property is undefined and must be ignored. When applying transforms to a view, you must use the view’s bounds
and center
properties to get the size and position of the view. The frame rectangles of any subviews are still valid because they are relative to the view’s bounds.
重要: 若是一個視圖的transform屬性不是恆等變換,視圖的frame屬性值就是未定義並必須被忽視。當你給視圖應用變換時,你必須使用視圖的bounds 和 center屬性來獲取視圖的尺寸和位置。 任何子視圖的框架矩形任然有效,由於它們是相對於視圖的邊界的。
For information about modifying your view’s transform property at runtime, see 「Translating, Scaling, and Rotating Views.」For information about how to use transforms to position content during drawing, see Drawing and Printing Guide for iOS.
關於在運行時修改視圖變換屬性的更多信息,請看「Translating, Scaling, and Rotating Views.」 關於在繪圖時如何使用變換來定位內容的信息,請看Drawing and Printing Guide for iOS.
點與像素
In iOS, all coordinate values and distances are specified using floating-point values in units referred to as points. The measurable size of a point varies from device to device and is largely irrelevant. The main thing to understand about points is that they provide a fixed frame of reference for drawing.
在iOS裏,全部座標值和距離都是用浮點-點單位制值來指定的,簡稱爲點。從設備到設備衡量一個點的變化大小是沒有意義的。 理解點的主要緣由是它們給繪圖提供了一個固定的參考框架。
Table 1-1 lists the screen dimensions (measured in points) for different types of iOS-based devices in a portrait orientation. The width dimension is listed first, followed by the height dimension of the screen. As long as you design your interface to these screen sizes, your views will display correctly on the corresponding type of device.
表 1-1 列出了不一樣類型設備在垂直方向上的屏幕尺寸(按點衡量),這些尺寸都基於iOS。 屏幕的寬尺寸在前,高尺寸在後。 只要根據這些屏幕尺寸設計,視圖將在相關類型的設備上正確顯示。
Device |
Screen dimensions (in points) |
---|---|
iPhone and iPod touch |
320 x 480 |
iPad |
768 x 1024 |
The point-based measuring system used for each type of device defines what is known as the user coordinate space. This is the standard coordinate space you use for nearly all of your code. For example, you use points and the user coordinate space when manipulating the geometry of a view or calling Core Graphics functions to draw the contents of your view. Although coordinates in the user coordinate space sometimes map directly to the pixels on the device’s screen, you should never assume that this is the case. Instead, you should always remember the following:
基於點的測量系統應用於每種類型的設備定義,它被稱爲用戶座標空間。 幾乎全部代碼都使用該標準座標空間。 好比, 當你操縱視圖的幾何外形或調用內核圖形函數來繪製視圖的內容時, 你將使用點和用戶座標空間。 儘管用戶座標空間裏的座標有時直接跟設備屏幕上的像素相對應, 但你毫不要認爲它們就是同一種東西,你應用老是記住如下一點:
One point does not necessarily correspond to one pixel on the screen.
一個點並不必定對應於屏幕上的一個像素。
At the device level, all coordinates you specify in your view must be converted to pixels at some point. However, the mapping of points in the user coordinate space to pixels in the device coordinate space is normally handled by the system. Both UIKit and Core Graphics use a primarily vector-based drawing model where all coordinate values are specified using points. Thus, if you draw a curve using Core Graphics, you specify the curve using the same values, regardless of the resolution of the underlying screen.
在設備層面,有些時候,全部你在視圖裏指定的座標都必須被轉化爲像素。 然而, 在設備座標空間內映射用戶座標空間的點到像素的工做一般是由系統來完成的。 UIKit 和 Core Graphics(內核圖形)都使用一個主要基於矢量的繪圖模型,在那裏全部的座標值都是由點指定的。 所以, 若是你用內核圖形繪製一條弧形,你只要給弧形指一個相同值,不用管底層屏幕的分辨率。
When you need to work with images or other pixel-based technologies such as OpenGL ES, iOS provides help in managing those pixels. For static image files stored as resources in your application bundle, iOS defines conventions for specifying your images at different pixel densities and for loading the image that best matches the current screen resolution. Views also provide information about the current scale factor so that you can adjust any pixel-based drawing code manually to accommodate higher-resolution screens. The techniques for dealing with pixel-based content at different screen resolutions is described in 「Supporting High-Resolution Screens」 in Drawing and Printing Guide for iOS.
當你的工做中須要使用圖片或其它基於像素的技術(好比OpenGL ES)時,iOS幫助你管理那些像素。 對於在應用程序包裏做爲資源存儲的靜態圖片文件, iOS定義了給圖片指定不一樣像素密度的各類約定,這些約定還包括讓圖片以最接近當前屏幕分辨率的分辨率載入。視圖還提供了有關當前縮放因子的信息,這樣你就能手動調整任何基於像素的繪圖來適應高分辨率屏幕。 在不一樣屏幕分辨率下處理基於像素的內容的各類技術在 Drawing and Printing Guide for iOS 的 「Supporting High-Resolution Screens」 裏有詳細描述。
視圖的運行時交互模型
Any time a user interacts with your user interface, or any time your own code programmatically changes something, a complex sequence of events takes place inside of UIKit to handle that interaction. At specific points during that sequence, UIKit calls out to your view classes and gives them a chance to respond on behalf of your application. Understanding these callout points is important to understanding where your views fit into the system. Figure 1-7 shows the basic sequence of events that starts with the user touching the screen and ends with the graphics system updating the screen content in response. The same sequence of events would also occur for any programmatically initiated actions.
任什麼時候候當用戶跟你的用戶界面發生交互時, 或任什麼時候候當你本身的代碼在編程上改變一些東西時,UIKit框架內發生的一個復瑣事件序列就是用來處理該交互的。 在序列的一個特殊的點, UIKit 框架召喚出你的視圖類,給它們機會響應應用程序的行爲。 理解這些召喚點對於理解你的視圖在什麼地方融入系統很重要。 圖1-7顯示了事件的基本序列,從用戶觸摸屏幕開始到圖形系統更新屏幕內容響應事件結束。一樣的事件序列在任何程序初始化操做時都會發生。
Figure 1-7 UIKit interactions with your view objects
圖 1-7 UIKit 框架跟視圖對象的交互
The following steps break the event sequence in Figure 1-7 down even further and explain what happens at each stage and how you might want your application to react in response.
下面的步驟更進一步的分析了 圖1-7 中發生的事件, 解釋了每一步發生的什麼,以及你可能須要你的應用程序如何響應。
The user touches the screen.
用戶觸摸了屏幕。
The hardware reports the touch event to the UIKit framework.
硬件向UIKit 框架報告了該觸摸事件。
The UIKit framework packages the touch into a UIEvent
object and dispatches it to the appropriate view. (For a detailed explanation of how UIKit delivers events to your views, see Event Handling Guide for iOS.)
UIKit 框架把觸摸事件打包進一個 UIEvent 對象, 並把它發派給相應的視圖。(UIKit 如何傳遞事件到視圖的詳細解釋,請看Event Handling Guide for iOS)
The event-handling code of your view responds to the event. For example, your code might:
視圖的事件處理代碼響應該事件。 好比,你的代碼可能:
Change the properties (frame, bounds, alpha, and so on) of the view or its subviews.
改變視圖或它的子視圖的屬性(frame , bounds, alpha, 等等)。
Call the setNeedsLayout
method to mark the view (or its subviews) as needing a layout update.
調用 setNeedsLayout 方法來標記該視圖(或其子視圖),做爲一個須要更新的佈局。
Call the setNeedsDisplay
or setNeedsDisplayInRect:
method to mark the view (or its subviews) as needing to be redrawn.
調用setNeedsDisplay
或setNeedsDisplayInRect: 方法來標記視圖(或其子視圖),做爲須要被從新繪製。
Notify a controller about changes to some piece of data.
通知一個控制器有關一些數據塊的改變。
Of course, it is up to you to decide which of these things the view should do and which methods it should call.
固然,由你決定這些事情,哪些視圖須要作,哪些方法須要被調用。
If the geometry of a view changed for any reason, UIKit updates its subviews according to the following rules:
若是視圖的幾何外形由於任何緣由發生了改變, UIKit 參照如下規則更新它的子框架:
If you have configured autoresizing rules for your views, UIKit adjusts each view according to those rules. For more information about how autoresizing rules work, see 「Handling Layout Changes Automatically Using Autoresizing Rules.」
若是你已經給你的視圖設置了自動調整大小規則, UIKit 根據那些規則調整每一個視圖。 更多有關自動調整大小規則是如何工做的信息,請看「Handling Layout Changes Automatically Using Autoresizing Rules.」
If the view implements the layoutSubviews
method, UIKit calls it.
若是視圖實現了layoutSubviews 方法, UIKit 框架調用它。
You can override this method in your custom views and use it to adjust the position and size of any subviews. For example, a view that provides a large scrollable area would need to use several subviews as 「tiles」 rather than create one large view, which is not likely to fit in memory anyway. In its implementation of this method, the view would hide any subviews that are now offscreen or reposition them and use them to draw newly exposed content. As part of this process, the view’s layout code can also invalidate any views that need to be redrawn.
你能夠在你的自定義視圖裏重載該方法, 並用它調整任何子視圖的位置及大小。 好比, 一個提供大滾動區域的視圖須要使用幾個子視圖做爲瓦片(tiles), 而不是建立一個不管如何也不太可能適應內存的大視圖。在該方法的實現中,視圖可能隱藏任何如今不用顯示的子視圖,或者從新定位它們並使用它們去繪製新暴露的內容。做爲該過程的一部分, 視圖佈局代碼也可讓須要被重畫的任何視圖無效。
If any part of any view was marked as needing to be redrawn, UIKit asks the view to redraw itself.
若是任何視圖的任何部分被標記爲須要被重畫, UIKit 要求視圖重畫它本身。
For custom views that explicitly define a drawRect:
method, UIKit calls that method. Your implementation of this method should redraw the specified area of the view as quickly as possible and nothing else. Do not make additional layout changes at this point and do not make other changes to your application’s data model. The purpose of this method is to update the visual content of your view.
對於明肯定義了一個 drawRect: 方法的自定義視圖, UIKit 調用那個方法。 該方法的實現應該是儘量快的重畫視圖的指定區域,而不作其它任何事情。 不要在該這時候作額外的佈局改變, 也不要給應用程序數據模型作任何其它改變。 該方法的目的是更新視圖的可見內容。
Standard system views typically do not implement a drawRect:
method but instead manage their drawing at this time.
標準系統視圖一般不會實現一個drawRect:方法, 可是會在這時候管理它們的繪圖。
Any updated views are composited with the rest of the application’s visible content and sent to the graphics hardware for display.
全部視圖更新會被合併到應用程序可見內容的其他部分中,並被髮送給圖形硬件以便顯示。
The graphics hardware transfers the rendered content to the screen.
圖形硬件在屏幕上繪製這些內容。
Note: The preceding update model applies primarily to applications that use standard system views and drawing techniques. Applications that use OpenGL ES for drawing typically configure a single full-screen view and draw directly to the associated OpenGL graphics context. In such a case, the view would still handle touch events but, because it is full-screen, it would not need to lay out subviews or implement a drawRect:
method. For more information about using OpenGL ES, see OpenGL ES Programming Guide for iOS.
注意: 先前的更新模型主要應用於使用標準系統視圖以及繪圖技術的應用程序。一般使用OpenGL ES來繪製的應用程序都配置了一個全屏視圖, 並直接在相關的OpenGL圖形上下文上繪製。 在這種狀況下,視圖可能任然須要處理觸摸事件,可是由於它是全屏的,它可能不須要佈局子視圖或實現一個drawRect:方法。 更多使用OpenGL ES的信息,請看OpenGL ES Programming Guide for iOS.
In the preceding set of steps, the primary integration points for your own custom views are:
在前面的步驟中,你自定義視圖的主要交互點是:
The event-handling methods:
事件處理方法:
The layoutSubviews
method
layoutSubviews 方法
The drawRect:
method
drawRect:方法
These are the most commonly overridden methods for views but you may not need to override all of them. If you use gesture recognizers to handle events, you do not need to override any of the event-handling methods. Similarly, if your view does not contain subviews or its size does not change, there is no reason to override the layoutSubviews
method. Finally, the drawRect:
method is needed only when the contents of your view can change at runtime and you are using native technologies such as UIKit or Core Graphics to do your drawing.
這些是視圖最常重載的方法,可是你可能不須要所有重載。 若是你使用手勢辨認器來處理事件,你就不須要重載任何一個事件處理方法。 一樣地,若是你的視圖不包含子視圖或它的尺寸不會改變,也沒有緣由要重載layoutSubviews 方法。 最後, 當你的視圖內容在運行時能發生改變時,drawRect:方法是你僅需重載的一個方法, 而且你使用本地技術,好比UIKit 或 Core Graphics 來完成繪圖。
It is also important to remember that these are the primary integration points but not the only ones. Several methods of theUIView
class are designed to be override points for subclasses. You should look at the method descriptions in UIView Class Reference to see which methods might be appropriate for you to override in your custom implementations.
請記住這些方法是主要的交互點,但不是隻有這些點才能夠交互。 UIView的一些方法也能夠被設計能夠成爲子類們的重載點(override points)。你應該在UIView Class Reference 裏查看方法說明,查看它們哪些方法適合你在自定義實現裏重載。
高效使用視圖的訣竅
Custom views are useful for situations where you need to draw something the standard system views do not provide, but it is your responsibility to ensure that the performance of your views is good enough. UIKit does everything it can to optimize view-related behaviors and help you achieve good performance in your custom views. However, you can help UIKit in this aspect by considering the following tips.
在你須要繪製一些標準系統視圖不能提供的內容的狀況下,自定義視圖是頗有用的,可是你必須負責確保你的視圖性能已經足夠好。 UIKit 作了一切它能作的來優化視圖相關行爲,並幫助你在你的自定義視圖裏實現好的性能。 可是, 你還能夠經過考慮如下提示來優化UIKit的這方面。
Important: Before optimizing your drawing code, you should always gather data about your view’s current performance. Measuring the current performance lets you confirm whether there actually is a problem and, if there is, gives you a baseline measurement against which you can compare future optimizations.
重要:在你優化你的繪圖代碼前,你應該老是收集有關視圖當前性能的數據。測量當前的性能讓你肯定是否確實存在問題,若是是,它還給你一個跟未來的優化進行比較的基線測量。
1、視圖不必定總有一個相應的視圖控制器
There is rarely a one-to-one relationship between individual views and view controllers in your application. The job of a view controller is to manage a view hierarchy, which often consists of more than one view used to implement some self-contained feature. For iPhone applications, each view hierarchy typically fills the entire screen, although for iPad applications a view hierarchy may fill only part of the screen.
應用程序的獨立視圖和視圖控制器之間不多存在一對一的關係。 視圖控制器的工做是管理視圖層次,視圖層次經常有多個視圖構成,它們被用來實現一些它們本身的功能。 對於iPhone應用程序,每一個視圖層次一般都裝有整個屏幕,儘管對於iPad應用程序來講一個視圖層次可能只裝有屏幕的一部分。
As you design your application’s user interface, it is important to consider the role that view controllers will play. View controllers provide a lot of important behaviors, such as coordinating the presentation of views on the screen, coordinating the removal of those views from the screen, releasing memory in response to low-memory warnings, and rotating views in response to interface orientation changes. Circumventing these behaviors could cause your application to behave incorrectly or in unexpected ways.
當你設計你的用戶界面時, 考慮視圖控制器的角色很重要。 視圖控制器提供了不少重要的行爲, 好比協調在屏幕上的視圖, 協調從屏幕移除的視圖, 響應低內存警告釋放內存, 以及響應界面方面變換事件旋轉視圖。 規避這些行爲能致使應用程序行爲錯誤或者以意想不到的方式行爲。
For more information view controllers and their role in applications, see View Controller Programming Guide for iOS.
有關視圖控制器以及它們在應用程序裏所扮演的角色等的更多信息,請看View Controller Programming Guide for iOS.
2、最少化自定義繪圖
Although custom drawing is necessary at times, it is also something you should avoid whenever possible. The only time you should truly do any custom drawing is when the existing system view classes do not provide the appearance or capabilities that you need. Any time your content can be assembled with a combination of existing views, your best bet is to combine those view objects into a custom view hierarchy.
儘管有時自定義繪圖很必要,可是這也是任什麼時候候你應該儘量避免的事情。只有當存在的系統視圖類確實沒法知足你須要的外形或能力時,你才須要決定作一些自定義繪圖。 任什麼時候候若是你的內容能夠經過已存在的視圖組合得到,最好的解決方法就是把這些視圖對象組合到一個自定義視圖層次裏。
3、利用各類內容模式
Content modes minimize the amount of time spent redrawing your views. By default, views use theUIViewContentModeScaleToFill
content mode, which scales the view’s existing contents to fit the view’s frame rectangle. You can change this mode as needed to adjust your content differently, but you should avoid using theUIViewContentModeRedraw
content mode if you can. Regardless of which content mode is in effect, you can always force your view to redraw its contents by calling setNeedsDisplay
or setNeedsDisplayInRect:
.
內容模式能讓你重畫視圖的總時間最小化。 默認狀況下,視圖使用UIViewContentModeScaleToFill 內容模式,該模式縮放視圖現有的內容來填充視圖的框架矩形。你能夠根據須要改變該模式來對內容進行不一樣的調整, 可是若是能夠,你應該避免使用UIViewContentModeRedraw 內容模式。無論哪一個內容模式在起做用,你老是能夠強制視圖對內容進行重畫,只要調用
setNeedsDisplay
或 setNeedsDisplayInRect:方法。
4、任什麼時候候儘量的聲明不透明視圖
UIKit uses the opaque
property of each view to determine whether the view can optimize compositing operations. Setting the value of this property to YES
for a custom view tells UIKit that it does not need to render any content behind your view. Less rendering can lead to increased performance for your drawing code and is generally encouraged. Of course, if you set the opaque
property to YES
, your view must fills its bounds rectangle completely with fully opaque content.
UIKit 使用視圖的 opaque 屬性來決定視圖是否能夠優化合成操做。 把自定義視圖的opaque屬性設置爲YES,告訴UIKit不須要渲染在本視圖後面的任何內容。更少的渲染能加強你的繪圖代碼性能,一般被鼓勵使用。 固然,若是你把opaque屬性設置爲YES,視圖必須所有用不透明內容來填滿整個邊界矩形。
5、在滾動時調整視圖的繪製行爲
Scrolling can incur numerous view updates in a short amount of time. If your view’s drawing code is not tuned appropriately, scrolling performance for your view could be sluggish. Rather than trying to ensure that your view’s content is pristine at all times, consider changing your view’s behavior when a scrolling operation begins. For example, you can reduce the quality of your rendered content temporarily or change the content mode while a scroll is in progress. When scrolling stops, you can then return your view to its previous state and update the contents as needed.
滾動能在很短的時間內發動多個視圖更新。 若是沒有適當的調整你的繪製代碼, 視圖的滾動性能會很慢。與其嘗試確保你的視圖內容始終都是最新的, 不如考慮當一個滾動操做開始時改變視圖的行爲。 好比, 你能夠暫時的下降你的渲染內容的質量或者滾動時改變內容模式。當滾動中止後,你能夠把視圖返回到它的前一個狀態,並根據須要更新內容。
6、不要經過嵌入子視圖來定製控制
Although it is technically possible to add subviews to the standard system controls—objects that inherit from UIControl
—you should never customize them in this way. Controls that support customizations do so through explicit and well-documented interfaces in the control class itself. For example, the UIButton
class contains methods for setting the title and background images for the button. Using the defined customization points means that your code will always work correctly. Circumventing these methods, by embedding a custom image view or label inside the button, might cause your application to behave incorrectly now or at some point in the future if the button’s implementation changes.
儘管把子視圖加入標準系統控制在技術上是可能的----繼承自UIControl的對象----你毫不應該以這種方式自定義它們。支持定製的控制經過位於控制類自身內部的明確並有被很好記載的接口來實現。好比, UIButton類包含了給按鈕設置標題和背景圖片的方法。 使用定義的定製點(customization points)意味着你的代碼將永遠能正確工做。 經過在按鈕裏嵌入一個自定義圖片視圖或標籤來規避(Circumventing)這些方法,若是按鈕的實現改變時,可能致使應用程序當即或在未來的某個點發生行爲錯誤。