【IOS筆記】View Programming Guide for iOS -1

原文:View Programming Guide for iOShtml

View and Window Architecture

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

 

Whether you use the system views or create your own custom views, you need to understand the infrastructure provided by the UIView and UIWindowclasses. 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.ios

 不管是使用系統提供的views仍是建立你的自定義views,你都須要理解UIView和UIWindow提供的類架構。這些類提供了精緻的設施來組織視圖的佈局和表現。若是理解了這些機制,在你修改代碼的時候你就更能確信程序是運行正常的。express

View Architecture Fundamentals

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.編程

一個View對象定義了一個屏幕上的矩形,並負責矩形區域中的繪製和touch事件。一個view也可做爲其餘views的父視圖,並負責協調子視圖的位置和大小。windows

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.數組

UIKit中的每一個view都有一個layer 對象(一般是一個CALayer類的實例)架構

在須要更精細控制渲染和動畫的場合,就須要操做view的layer對象。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 ViewTransitionssample 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.less

Figure 1-1  Architecture of the views in a sample application

 

View Hierarchies and Subview Management

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.

除了提供本身的內容,一個view還可做爲其餘views的容器。childview-subview,parentview-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.

子視圖佔據父視圖部分或所有的位置。不透明子視圖;半透明的;

父視圖使用一個有序數組存儲子視圖,這對每一個視圖的可見性是有影響的。相互覆蓋。

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.

superview-subview 關係還影響視圖的幾個行爲:父視圖大小改變對子視圖大小、位置影響的連鎖反應。父視圖的隱藏;改變父視圖的alpha值,對父視圖的座標系應用數學變換;

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.

視圖層次的排列方式也會決定app對事件的響應。當一個view內部發生了touch事件,系統直接將包含touch信息的事件對象發送給那個view處理。若是這個view不處理,它能夠將event對象傳遞給父視圖。若是父視圖不處理,能夠繼續向上傳遞,造成一個響應鏈。一個視圖也能夠傳遞事件對象給view controller這樣的居中響應對象。若是沒有對象處理這個事件,它最終會到達application對象,而application一般會丟棄它。

For more information about how to create view hierarchies, see Creating and Managing a View Hierarchy.

 

The View Drawing Cycle

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類使用按需繪製的模型。當一個視圖第一次在屏幕上呈現,系統會要求視圖繪製他的內容。系統會撲捉下視圖的屏幕快照做爲視圖的可視化呈現。若是你沒有改變視圖的內容,系統就不會再調用視圖的繪製代碼。快照圖像會多重用,若是你改變了視圖的內容,你通知系統視圖已經改變,系統會從新調用繪製代碼,而且捕捉新的快照。

When the contents of your view change, you do not redraw those changes directly. Instead, you invalidate the view using either the setNeedsDisplay orsetNeedsDisplayInRect: 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 orsetNeedsDisplayInRect方法使其失效便可。這些方法告訴系統視圖已經改變,須要在下次重繪。系統在當前run loop結束前一直等到,直到發起任何繪圖操做。這個延遲,給你有機會將多個視圖失效、或從你的視圖層次中添加或移除視圖,隱藏視圖,改變視圖大小,改變視圖位置 等等。全部這些改變會在同一個時間生效。

Note: Changing a view’s geometry does not automatically cause the system to redraw the view’s content. The view’s contentMode 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 mode拉伸或在視圖邊界內改變當前快照的位置,而不會從新建立一個快照。 

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 the drawRect:method is the most common technique.

當重繪視圖內容的時機來到時,實際的繪製過程因爲views和其配置的不一樣而不一樣。系統視圖一般實現私有的繪製方法來渲染它們的內容。系統視圖一般會暴露可供你配置視圖實際表現方式的接口。對於自定義UIView的子類,一般你須要override 子視圖的drawRect方法。還有其餘方式來提供視圖的內容,例如直接修改下層的layer對象,可是override drawRect方法是最經常使用的技術。

For more information about how to draw content for custom views, see Implementing Your Drawing Code.

 

Content Modes

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.

每一個視圖都有一個content mode,控制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.

視圖的內容模式應用於:

  • 改變視圖frame或bounds的寬或高;
  • 給視圖的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,這致使視圖的內容會被拉伸以適應新的frame大小。圖1-2展現了一些內容模式的表現。不是全部內容模式都會徹底填滿視圖邊界,而填滿的會扭曲視圖內容。

 

Figure 1-2  Content mode comparisons

Content mode comparisons

 

 

Content modes are good for recycling the contents of your view, but you can also set the content mode to the UIViewContentModeRedraw 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.

 content mode對於視圖內容的再利用有好處,不過在你但願在縮放或改變大小事也重繪視圖時,你也能夠將視圖模式設置爲UIViewContentModeRedraw。設置這個值,會強制系統在幾何變化時每次都調用視圖的drawRect方法。一般,你應該儘量避免使用這個設置,對於標準系統視圖則應該壓根也不使用。

For more information about the available content modes, see UIView Class Reference.

 

Stretchable Views

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.

你能夠指定視圖的一部分做爲可伸縮的,從而當視圖大小改變時,僅僅只有可伸縮部分的內容受影響。典型使用可伸縮區域的例子,如按鈕,定義了重複模式。你指定的可伸縮區域可容許沿着一個或兩個座標軸伸縮。固然,若是可沿兩個軸縮放,則視圖的邊也必須定義可重複模式以免變形。

Figure 1-3  Stretching the background of a button

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屬性定義可伸縮區域。

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, and UIViewContentModeScaleAspectFill 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.

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.

 

Built-In Animation Support

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 areanimatable—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:

  1. Tell UIKit that you want to perform an animation.

  2. Change the value of the property.

爲每一個view都提供一個layer對象的好處是爲視圖改變提供動畫變得很是方便。在與用戶交互信息方面動畫很是重要,在設計app時須要始終考慮這個方面。UIView的許多屬性都是支持動畫的,也就是說,半自動的支持以動畫形式從一個值變到另外一個值。爲使用動畫屬性,你須要:

一、告訴UIKit你但願之星一個動畫;

二、改變屬性值;

Among the properties you can animate on a UIView object are the following:

下面的屬性是支持動畫的:

  • frame—Use this to animate position and size changes for the view.

  • bounds—Use this to animate changes to the size of the view.

  • center—Use this to animate the position of the view.

  • transform—Use this to rotate or scale the view.

  • alpha—Use this to change the transparency of the view.

  • backgroundColor—Use this to change the background color of the view.

  • contentStretch—Use this to change how the view’s contents stretch.

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.

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.

For details about how to perform view-based animations, see Animations. For more information about creating animations using Core Animation, seeCore Animation Programming Guide and Core Animation Cookbook.

 

View Geometry and Coordinate Systems

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顯示了屏幕座標系。window和view也定義了它們本身的座標系。

Figure 1-4  Coordinate system orientation in UIKit

View coordinate system

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. TheUIWindow and UIView classes both include methods to help you convert from one coordinate system to another.

因爲每一個view和window都定義了本身的座標系,你須要在任什麼時候候都關注哪一個座標系在生效。每一次你在view中繪圖或者改變幾何形狀,都與某座標系相關。在繪圖時,你使用的是視圖本身的座標系。在作幾何變換時,你使用父視圖的座標系。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.

 注意:Core Graphics and OpenGL ES等IOS技術使用了不一樣於UIKit的座標系。

The Relationship of the Frame, Bounds, and Center Properties

A view object tracks its size and location using its framebounds, and center properties:

view對象使用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屬性包含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), thecenter property is the preferred way to do so. The value in the center 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屬性是最方便的途徑。ceter屬性值老是有效,甚至在你縮放和旋轉視圖的時候。而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),它的大小與frame矩形相同。你在矩形範圍內繪製的任何東西都是視圖可見內容的一部分。若是你改變了bounds矩形的原點,在新矩形中的內容則變成了視圖的可見部分。

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.

Figure 1-5  Relationship between a view's frame and boundsRelationship between a view's frame and bounds

Although you can change the framebounds, 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 centerproperty similarly changes to match the new center point of the frame rectangle.當你改變frame屬性,會改變bounds的size。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的size。

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.

缺省地,一個視圖的frame不裁剪於父視圖的frame。所以,任何伸出父視圖邊界的子視圖仍會渲染。你能夠經過設置父視圖的 clipsToBounds 屬性爲YES,來改變這個默認行爲。

不管子視圖在父視圖顯示時是否裁剪,touch事件始終會限制在父視圖的範圍內觸發。

Coordinate System Transformations

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:

  • To modify your entire view, modify the affine transform in the transform property of your view.

  • To modify specific pieces of content in your view’s drawRect: method, modify the affine transform associated with the active graphics context.

座標系統變換給予你快速方便改變視圖的方法。仿射變換是一個數學矩陣,它定義了一個點如何從一個座標系映射到另一個。你能夠對整個視圖應用仿射變換以改變大小,位置或相對於父視圖的方向。你也能夠在你的繪圖代碼中使用仿射變換來爲許多內容執行相同操做。如何應用仿射變換依賴於上下文:

  • 改變整個視圖,修改transform屬性;
  • 改變部份內容,在視圖的drawRect方法中;

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.

 

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獲得仿射變換,而且在繪圖過程當中你可以使用相關的Core Graphics 函數改變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 your drawRect: method, the CTM is the affine transform associated with the active graphics context.

當前使用的transformation matrix (CTM) 是仿射變換。當操做整個視圖的幾何圖形,CTM是存儲在視圖transform屬性中的放射變換。

The coordinate system of each subview builds upon the coordinate systems of its ancestors. So when you modify a view’s transform 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演示了兩種不一樣的旋轉參數是若是最終影響圖形繪製的。

Figure 1-6  Rotating a view and its content

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屬性不是 identity transform,視圖的frame屬性值是未定義的,而且須要忽略。當對一個視圖應用transform,你必須使用視圖的bounds和center屬性來獲得大小和位置。全部子視圖的frame矩形仍然是合法值,由於它們是相對於視圖的bounds。

 

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.

 

Points Versus Pixels

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中,全部座標值和距離用浮點數來度量,單位是point。不一樣設備的point尺寸大小差異很大。point的方式使得在不一樣設備上的frame值是固定的。

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.

Table 1-1  Screen dimensions for iOS-based devices

Device

Screen dimensions (in points)

iPhone and iPod touch devices with 4-inch Retina display

320 x 568

Other iPhone and iPod touch devices

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.

每一個設備使用的,基於point的度量系統定義了用戶座標空間。這是標準座標空間。

你須要始終記着:

  • 一個point不須要必定等於屏幕上的一個像素。

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.

在設備級別,全部你在視圖中使用的座標都要轉換成像素。然而從基於point的用戶座標空間到基於像素的設備座標空間的轉換,是由系統來處理的。UIKit and Core Graphics使用的基於矢量的繪圖模型都是使用的point座標。所以,當你使用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 Views in Drawing and Printing Guide for iOS.

當你須要使用圖像等基於像素的技術,例如OpenGL ES,iOS爲使用像素提供了幫助。對於在app bundle中存儲的靜態圖像資源,iOS定義了指定像素密度的參數。視圖還提供了縮放因子,從而你能夠手工調整任何基於像素的代碼來適配高分屏。

The Runtime Interaction Model for Views

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-7shows 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.

用戶在與user interface交互的任什麼時候候,或者任何經過編程方式修改的時候,在UIKit內部會爲此交互產生一系列複雜的動做。理解下圖中的標註,對於理解視圖如何適應系統是很重要的。圖1-7展現了從用戶touch屏幕到最終更新屏幕顯示所發生的一系列事件。對於經過編程方式出發的動做也是這個序列。

Figure 1-7  UIKit interactions with your view objectsUIKit interactions with your view objects

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中的序列分解的更加詳細:

  1. The user touches the screen.用戶touche屏幕

  2. The hardware reports the touch event to the UIKit framework.硬件向UIKit 報告touch事件。

  3. 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將touch打包到UIEvent對象,分發給相應view(詳情參考 Event Handling Guide for iOS

  4. 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.改變view及subview的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.通知controller改變

    Of course, it is up to you to decide which of these things the view should do and which methods it should call.固然,視圖應該如何作,調用哪一個方法可由你決定。

  5. If the geometry of a view changed for any reason, UIKit updates its subviews according to the following rules:若是視圖的幾何形狀無論什麼緣由改變了,UIKit根據如下規則更新其子視圖:

    1. 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根據這些規則調整每一個視圖。

    2. 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.你能夠override這個方法來調整子視圖的大小和位置。例如,一個具備很大滾動區域的視圖會使用幾個子視圖而不是一個大視圖,大視圖太佔用內存。在具體實現方法中,視圖會隱藏不在屏幕上顯示的部分,而後在須要顯示的時候再重繪。

  6. 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方法,但也會在這個時候完成繪製。

  7. Any updated views are composited with the rest of the application’s visible content and sent to the graphics hardware for display.任何更新後的視圖與app的其他部分整合,而後被髮送到圖形硬件來顯示。

  8. 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 ES graphics context. In such a case, the view may still handle touch events but, because it is full-screen, it would not need to lay out subviews. For more information about using OpenGL ES, see OpenGL ES Programming Guide for iOS.

 

In the preceding set of steps, the primary integration points for your own custom views are:

在前述的步驟中,自定義視圖的主要集成點是:

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 the UIView 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還設計了幾個方法以方便在子類中覆蓋。你能夠參考UIView Class Reference 來找到合適的方法。

Tips for Using Views Effectively  高效使用視圖的提示

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.

 重要:在優化你的繪圖代碼以前,你須要先收集測量數據

Views Do Not Always Have a Corresponding View Controller 視圖不老是須要一個視圖控制器

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.

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.

Minimize Custom Drawing 儘量少的自定義繪製

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.

Take Advantage of Content Modes  利用內容模式的優勢

Content modes minimize the amount of time spent redrawing your views. By default, views use the UIViewContentModeScaleToFill 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 the UIViewContentModeRedraw 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:.

Declare Views as Opaque Whenever Possible 儘量將視圖定義爲不透明的

UIKit uses the opaque property of each view to determine whether the view can optimize compositing operations. Setting the value of this property to YESfor 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 fill its bounds rectangle completely with fully opaque content.

將opaque置爲YES可明確告訴UIKit不須要繪製底層的內容

Adjust Your View’s Drawing Behavior When Scrolling 經過滾動調整視圖的繪製行爲

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.

Do Not Customize Controls by Embedding Subviews 不要經過簽入子視圖來自定義控件

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, theUIButton 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.

相關文章
相關標籤/搜索