View Programming Guide for iOS 閱讀筆記
(個(gè)人學(xué)習(xí)記錄,從文檔中摘抄出部分,谷歌翻譯+手改,語句略生硬,錯(cuò)誤之處歡迎指正)
(一) View and Window Architecture
View Architecture Fundamentals
視圖與Core Animation圖層一起工作來處理視圖內(nèi)容的渲染和動(dòng)畫。 UIKit中的每個(gè)視圖都由layer對象(通常是CALayer類的實(shí)例)支持,該對象管理視圖的后備存儲并處理與視圖相關(guān)的動(dòng)畫。你執(zhí)行的大多數(shù)操作應(yīng)該通過UIView接口。但是,在需要更多地控制視圖的渲染或動(dòng)畫行為的情況下,您可以通過其layer執(zhí)行操作。
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
UIViewinterface. 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.
bar button item按鈕本身不是視圖(不是繼承于UIView),但它內(nèi)部管理著一個(gè)視圖。
bar button item (which is not a view itself but which manages a view internally)
每個(gè)視圖都有一個(gè)相應(yīng)的圖層對象,可以從該view的layer屬性中進(jìn)行訪問。 (因?yàn)閎ar button不是view,所以不能直接訪問它的layer。)這些layer對象的背后是Core Animation渲染對象,最終是由硬件中的緩沖區(qū)來管理屏幕上的實(shí)際顯示位。
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.
Core Animation layer 對象的使用對性能有重要影響。視圖對象的實(shí)際繪圖代碼盡可能少地調(diào)用,并且在調(diào)用代碼時(shí),結(jié)果由Core Animation緩存并在稍后重用。重用已經(jīng)呈現(xiàn)的內(nèi)容消除了更新視圖通常需要的昂貴的繪圖周期。在內(nèi)容可以被操縱的動(dòng)畫中,重用這些內(nèi)容尤為重要。這種重復(fù)使用比創(chuàng)建新內(nèi)容要便宜得多。
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.
View Hierarchies and Subview Management
每個(gè)父視圖都將其子視圖存儲在有序數(shù)組中,并且該數(shù)組中的順序也會影響每個(gè)子視圖的可見性。如果兩個(gè)兄弟子視圖彼此重疊,則最后添加的子視圖(或移動(dòng)到子視圖數(shù)組的末尾)會呈現(xiàn)在另一個(gè)之上。
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.
父視圖 - 子視圖關(guān)系也會影響多個(gè)視圖行為。更改父視圖的大小會產(chǎn)生連鎖效應(yīng),從而導(dǎo)致任何子視圖的大小和位置也發(fā)生變化。當(dāng)您更改父視圖的大小時(shí),可以通過適當(dāng)?shù)嘏渲靡晥D來控制每個(gè)子視圖的調(diào)整大小行為。影響子視圖的其他更改包括隱藏父視圖、更改父視圖的alpha(透明度)或?qū)?shù)學(xué)變換應(yīng)用于父視圖的坐標(biāo)系。
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.
視圖層次結(jié)構(gòu)中的視圖排列也決定了您的應(yīng)用程序如何響應(yīng)事件。當(dāng)在特定視圖內(nèi)發(fā)生觸摸時(shí),系統(tǒng)將帶有觸摸信息的事件對象直接發(fā)送到該視圖進(jìn)行處理。但是,如果視圖不處理特定的觸摸事件,它可以將事件對象傳遞給它的父視圖。如果父視圖不處理事件,它將事件對象傳遞給它的父視圖,以此類推到響應(yīng)者鏈。特定視圖也可以將事件對象傳遞給干預(yù)響應(yīng)者對象,如視圖控制器。如果沒有對象處理事件,它最終會到達(dá)應(yīng)用程序?qū)ο?,通常會丟棄它。
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.
The View Drawing Cycle
UIView類使用按需繪制模型來呈現(xiàn)內(nèi)容。當(dāng)視圖第一次出現(xiàn)在屏幕上時(shí),系統(tǒng)會要求它繪制其內(nèi)容。系統(tǒng)捕獲此內(nèi)容的快照并將該快照用作視圖的視覺呈現(xiàn)。如果你永遠(yuǎn)不改變視圖的內(nèi)容,視圖的繪圖代碼可能永遠(yuǎn)不會再被調(diào)用。大多數(shù)涉及視圖的操作都會重用快照圖像。如果您更改內(nèi)容,則會通知系統(tǒng)視圖已更改。該視圖然后重復(fù)繪制視圖并捕獲新結(jié)果的快照的過程。
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.
當(dāng)視圖的內(nèi)容發(fā)生變化時(shí),您不會直接重繪這些更改。而是使用setNeedsDisplay或setNeedsDisplayInRect:方法使視圖無效。這些方法告訴系統(tǒng),視圖的內(nèi)容發(fā)生了變化,需要在下一次機(jī)會中重新繪制。在啟動(dòng)任何繪圖操作之前,系統(tǒng)會等待當(dāng)前運(yùn)行循環(huán)的結(jié)束。這種延遲使您有機(jī)會使多個(gè)視圖失效,從您的層次結(jié)構(gòu)中添加或刪除視圖,隱藏視圖,調(diào)整視圖大小以及一次重新定位視圖。然后,您所做的所有更改都會同時(shí)反映出來。
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.
注:更改視圖的幾何圖形不會自動(dòng)導(dǎo)致系統(tǒng)重新繪制視圖的內(nèi)容。視圖的contentMode屬性決定了如何解釋對視圖幾何體的更改。大多數(shù)內(nèi)容模式在視圖的邊界內(nèi)拉伸或重新定位現(xiàn)有快照,并且不會創(chuàng)建新的快照。
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.
當(dāng)需要渲染視圖的內(nèi)容時(shí),實(shí)際繪圖過程會根據(jù)視圖及其配置而變化。系統(tǒng)視圖通常實(shí)現(xiàn)私有繪圖方法來呈現(xiàn)其內(nèi)容。系統(tǒng)視圖通常會公開可用于配置視圖實(shí)際外觀的接口。對于自定義UIView子類,通常會重寫視圖的drawRect:方法,并使用該方法繪制視圖的內(nèi)容。還有其他方法可以提供視圖的內(nèi)容,例如直接設(shè)置底層的內(nèi)容,但重寫drawRect:方法是最常用的技術(shù)。
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
UIViewsubclasses, 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.
Content Modes
每個(gè)視圖都有一個(gè)內(nèi)容模式,用于控制視圖如何重復(fù)利用其內(nèi)容以響應(yīng)視圖幾何體的更改以及是否回收其內(nèi)容。首次顯示視圖時(shí),它會像往常一樣渲染其內(nèi)容,并將結(jié)果捕獲到底層位圖中。之后,對視圖幾何體的更改并不總是會導(dǎo)致重新創(chuàng)建位圖。相反,contentMode屬性中的值決定是否縮放位圖以適應(yīng)新的邊界,或者只是固定到視圖的一個(gè)角或邊緣。
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.
內(nèi)容模式適合重復(fù)利用視圖的內(nèi)容,但您也可以將內(nèi)容模式設(shè)置為UIViewContentModeRedraw值自定義視圖在縮放和調(diào)整大小操作期間重繪自己。將視圖的內(nèi)容模式設(shè)置為該值會迫使系統(tǒng)根據(jù)幾何變化調(diào)用視圖的drawRect:方法。一般而言,您應(yīng)該盡可能避免使用此值,并且您絕對不應(yīng)該將其用于標(biāo)準(zhǔn)系統(tǒng)視圖。
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.
Stretchable Views
注:文檔中的方法contentStretch已被棄用了,改用resizableImageWithCapInsets:
只有內(nèi)容模式為UIViewContentModeScaleToFill,UIViewContentModeScaleAspectFit和UIViewContentModeScaleAspectFill 時(shí)才支持可伸縮視圖。如果您指定將內(nèi)容固定到邊或角的內(nèi)容模式(因此實(shí)際上并不縮放內(nèi)容),視圖將忽略可拉伸區(qū)域。
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.
The Relationship of the Frame, Bounds, and Center Properties
主要使用center和frame屬性來操作當(dāng)前視圖的幾何圖形。
其中center屬性始終有效,即使縮放或旋轉(zhuǎn)因子已添加到視圖的transform中。而frame屬性卻不是如此,如果視圖的transform不等于標(biāo)識identity transform,則該frame屬性被認(rèn)為是無效的。
You use the center and frame properties primarily for manipulating the geometry of the current view.
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.
雖然可以獨(dú)立更改frame,bounds和center屬性,但通過以下方式對一個(gè)屬性的更改會影響其他屬性:
- 當(dāng)您設(shè)置frame屬性時(shí),bounds屬性中的大小值將更改為與frame矩形的新大小相匹配。center屬性中的值同樣會更改為匹配frame矩形的新中心點(diǎn)。
- 當(dāng)您設(shè)置center屬性時(shí),frame中的原點(diǎn)值會相應(yīng)更改。
- 當(dāng)您設(shè)置bounds屬性的大小時(shí),frame屬性中的大小值將更改為與bounds矩形的新大小相匹配。
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:
- 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.
- When you set the center property, the origin value in the frame changes accordingly.
- 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.
默認(rèn)情況下,視圖的frame不會剪切到其父視圖的frame。因此,任何位于他們的父視圖frame之外的子視圖都將全部呈現(xiàn)。但是,您可以通過將父視圖的clipsToBounds屬性設(shè)置為YES來更改此行為。無論子視圖是否可視化剪切,觸摸事件只在父視圖的邊界矩形內(nèi)才響應(yīng)。換句話說,如果觸摸事件發(fā)生在父視圖邊界矩形之外,不會傳遞到該視圖。
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.
Coordinate System Transformations
- 要修改整個(gè)視圖,請?jiān)谝晥D的transform屬性中修改affine transform。
To modify your entire view, modify the affine transform in the transform property of your view.
- 要修改特定的內(nèi)容片段,在drawRect:方法中,修改與圖形上下文關(guān)聯(lián)的仿射變換。
To modify specific pieces of content in your view’s drawRect: method, modify the affine transform associated with the active graphics context.
當(dāng)您想要實(shí)現(xiàn)動(dòng)畫時(shí),通常會修改視圖的transform屬性。例如,您可以使用此屬性來創(chuàng)建圍繞其中心點(diǎn)旋轉(zhuǎn)的視圖動(dòng)畫。您不應(yīng)該使用transform屬性對視圖進(jìn)行永久更改(例如在其父視圖的坐標(biāo)空間中修改其視圖的位置或大?。瑢τ谶@種永久性的更改,您應(yīng)該修改視圖的frame。
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屬性時(shí),所有變換均相對于視圖的中心點(diǎn)執(zhí)行。
Note: When modifying the transform property of your view, all transformations are performed relative to the center point of the view.
每個(gè)子視圖的坐標(biāo)系建立在其祖先的坐標(biāo)系上。因此,當(dāng)您修改視圖的transform屬性時(shí),該更改會影響視圖及其所有子視圖。但是,這些更改僅影響屏幕上視圖的最終呈現(xiàn)。由于每個(gè)視圖都會繪制其內(nèi)容,并將其子視圖相對于其邊界進(jìn)行布局,因此它可以在繪制和布局期間忽略其父視圖的變換。
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屬性不是identity transform,那么該視圖的frame屬性值是未定義的,frame一定會被忽略。將transform應(yīng)用于視圖時(shí),必須使用視圖的bounds和center屬性來獲取視圖的大小和位置。任何子視圖的frame仍然有效,因?yàn)樗鼈兿鄬τ谝晥D的邊界。
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.
Points Versus Pixels
...
The Runtime Interaction Model for Views
- 用戶觸摸屏幕。
- 硬件將觸摸事件報(bào)告給UIKit框架。
- UIKit框架將觸摸事件打包到 UIEvent 對象中,并將其分派到適當(dāng)?shù)囊晥D。
- 由視圖的事件處理代碼 來響應(yīng)事件。
- 如果視圖的幾何因任何原因而更改,UIKit將根據(jù)以下規(guī)則更新其子視圖...
- 如果任何視圖的任何部分被標(biāo)記為需要重繪,UIKit會要求視圖重繪本身。
- 任何更新的視圖都與應(yīng)用程序的其余可見內(nèi)容合成并發(fā)送到圖形硬件以供顯示。
- 圖形硬件將渲染的內(nèi)容傳送到屏幕。
- The user touches the screen.
- The hardware reports the touch event to the UIKit framework.
- The UIKit framework packages the touch into a UIEvent object and dispatches it to the appropriate view.
- The event-handling code of your view responds to the event.
- If the geometry of a view changed for any reason, UIKit updates its subviews according to the following rules...
- If any part of any view was marked as needing to be redrawn, UIKit asks the view to redraw itself.
- 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.
如果視圖實(shí)現(xiàn)了layoutSubviews方法,UIKit會調(diào)用它。
您可以在自定義視圖中重寫此方法,并使用它來調(diào)整任何子視圖的位置和大小。 例如,提供大型可滾動(dòng)區(qū)域的視圖需要使用多個(gè)子視圖作為“圖塊”,而不是創(chuàng)建一個(gè)大視圖,而該視圖無論如何都不太適合內(nèi)存。 在實(shí)現(xiàn)這種方法時(shí),視圖會隱藏現(xiàn)在不在屏幕上的任何子視圖或重新定位它們并使用它們來繪制新呈現(xiàn)的內(nèi)容。 作為此過程的一部分,視圖的布局代碼也可以使任何需要重繪的視圖失效。
If the view implements the layoutSubviews method, UIKit calls it.
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.
對于顯式定義drawRect:方法的自定義視圖,UIKit會調(diào)用該方法。 你的這個(gè)方法的實(shí)現(xiàn)應(yīng)該盡可能快地重繪視圖的指定區(qū)域,而不是其他的。 此時(shí)不要進(jìn)行額外的布局更改,也不要對應(yīng)用程序的數(shù)據(jù)模型進(jìn)行其他更改。 此方法的目的是更新視圖的可視內(nèi)容。
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.
Tips for Using Views Effectively
1. Views Do Not Always Have a Corresponding View Controller
視圖控制器的工作是管理視圖層次結(jié)構(gòu),該視圖層次結(jié)構(gòu)通常包含多個(gè)用于實(shí)現(xiàn)一些獨(dú)立功能的視圖。
視圖控制器提供了許多重要的行為,例如協(xié)調(diào)屏幕上的視圖顯示,協(xié)調(diào)從屏幕移除這些視圖,釋放內(nèi)存以響應(yīng)低內(nèi)存警告,以及響應(yīng)界面方向更改而旋轉(zhuǎn)視圖。
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.
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.
2. Minimize Custom Drawing
雖然自定義繪圖有時(shí)是必要的,但它也是你應(yīng)該盡可能避免的東西。 只有當(dāng)現(xiàn)有的系統(tǒng)視圖類沒有提供您需要的外觀或功能時(shí),您才應(yīng)該真正做到任何自定義繪圖。 只要您的內(nèi)容可以與現(xiàn)有視圖組合在一起,最好的辦法就是將這些視圖對象組合到一個(gè)自定義視圖層次結(jié)構(gòu)中。
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. Take Advantage of Content Modes
內(nèi)容模式可以減少重繪視圖的時(shí)間。 默認(rèn)情況下,視圖使用UIViewContentModeScaleToFill內(nèi)容模式,該模式縮放視圖的現(xiàn)有內(nèi)容以適合視圖的frame。 您可以根據(jù)需要更改此模式以不同的方式調(diào)整您的內(nèi)容,但是如果可以的話,您應(yīng)該避免使用UIViewContentModeRedraw內(nèi)容模式。 不過,無論設(shè)置的是哪種內(nèi)容模式,您都可以通過調(diào)用setNeedsDisplay或setNeedsDisplayInRect:來強(qiáng)制視圖重繪其內(nèi)容。
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:.
4. Declare Views as Opaque Whenever Possible
UIKit使用每個(gè)視圖的opaque屬性來確定視圖是否可以優(yōu)化合成操作。 將自定義視圖的該屬性值設(shè)置為YES會告訴UIKit它不需要在視圖后面呈現(xiàn)任何內(nèi)容。 較少的渲染可以提高您的繪圖代碼的性能,并且通常會受到鼓勵(lì)。 當(dāng)然,如果將opaque屬性設(shè)置為YES,則視圖必須用完全不透明的內(nèi)容完全填充其frame。
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 theopaqueproperty toYES, your view mustfill its bounds rectangle completely with fully opaque content.
5. Adjust Your View’s Drawing Behavior When Scrolling
滾動(dòng)可以在很短的時(shí)間內(nèi)產(chǎn)生大量的視圖更新。 如果您的視圖的繪制代碼未適當(dāng)調(diào)整,則視圖的滾動(dòng)性能可能會很低。 在開始滾動(dòng)操作時(shí),可以嘗試不要試圖確保視圖的內(nèi)容始終處于原始狀態(tài),而應(yīng)考慮更改視圖的行為。 例如,您可以暫時(shí)降低渲染內(nèi)容的質(zhì)量,或在滾動(dòng)正在進(jìn)行時(shí)更改內(nèi)容模式。 當(dāng)滾動(dòng)停止時(shí),您可以將視圖恢復(fù)到之前的狀態(tài)并根據(jù)需要更新內(nèi)容。
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. Do Not Customize Controls by Embedding Subviews
盡管在技術(shù)上可以將子視圖添加到標(biāo)準(zhǔn)系統(tǒng)控件 - 從UIControl繼承的對象 - 您不應(yīng)該以這種方式定制它們。 支持自定義的控件通過控件類本身的明確和詳細(xì)記錄的接口來實(shí)現(xiàn)。 例如,UIButton類包含用于設(shè)置按鈕的標(biāo)題和背景圖像的方法。 使用定義的定制點(diǎn)意味著您的代碼將始終正常工作。 通過在按鈕中嵌入自定義圖像視圖或標(biāo)簽來限制這些方法,如果按鈕的實(shí)現(xiàn)發(fā)生更改,則可能會導(dǎo)致應(yīng)用程序現(xiàn)在或未來某個(gè)時(shí)刻的行為不正確。
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
UIButtonclass 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.