Core Animation Programming Guide - Core Animation Basics

Core Animation Basics

Core Animation 爲你的 app 提供視圖和其餘視覺元素的通常動畫建立。Core Animation 並非替代你 app 的視圖,它是一種集成在視圖中爲視圖內容提供更好性能和支持的動畫技術。它經過緩存視圖內容到位圖實現,能夠直接地被圖形硬件操做。有時這種緩存行爲須要你屢次考慮怎麼呈現和管理你 app 的內容,可是多數時候你使用 Core Animation 並不須要知道這種緩存技術。除了緩存視圖內容,Core Animation也定義一種方式來明確任意的視圖內容,並集成此內容到你的視圖中和其餘的一塊兒表現動畫。html

你用 Core Animation 把 app 視圖和可視對象的變化用動畫的形式表現出來,大多數都是經過修改視圖的屬性,好比,你可能使用 Core Animation 更新視圖的position,size或者 opacity。Core Animation 根據你指定的屬性值和現有值的不一樣造成動畫。你不須要想卡通動畫那樣每秒60次的替換視圖內容,只須要在屏幕中移動視圖、淡入淡出視圖內容,應用任意的圖形形態到視圖,或者改變視圖的可視屬性。ios

Layers Provide the Basic for Drawing and Animations

Layer 對象 是在3D空間中組織成的2D界面,是Core Animation 的核心。像視圖同樣,layer 管理着幾何、內容和界面的可視屬性之類的信息。不一樣於視圖的地方是它並不定義本身的形態。一個 Layer 僅僅管理圍繞着位圖的狀態信息。位圖自己既能夠是視圖的最終繪製形態,也能夠是一張你指定的圖片。所以,你在 app 中使用的核心 layer 主要管理的是數據,能夠當作數據模型。這一點須要謹記,它會影響到動畫的效果。緩存

The Layer-Based Drawing Model

在你的 app 中,大部分的 layer 並不作實際的繪製,只捕捉 app 提供的內容並緩存它們到位圖中,此位圖有時被做爲 backing store 。緩存到位圖以後修改 layer 的屬性,實際修改的都是 layer 對象相關的狀態信息。當 layer 的屬性值變動觸發動畫時,Core Animation 傳遞 layer 的位圖和狀態信息給圖形卡,圖形卡根據狀態信息渲染位圖,如圖 1-1 。用硬件渲染位圖比在軟件中快不少。性能優化

圖 1-1 How Core Animation draws content
app

因爲是直接操做靜態的位圖,layer-based 的繪製技術徹底不一樣於 view-based 的繪製技術。view-based 繪製,是視圖改變後調用自身的方法 drawRect: 根據新的參數重繪,這種方式會下降性能,由於重繪的動做是經過 CPU 計算後在主線程上完成的。Core Animation 經過圖形卡操做緩存的位圖分擔了CPU的負擔來完成形似或相同的效果。框架

儘管 Core Animation 儘量的使用緩存內容,你的 app 仍是得提供內容的初始化和一次次的更新。Providing a Layer's Contents 這一章節中會詳細地描述怎麼爲你的 app 提供 layer 內容對象。ide

Layer-Based 動畫

layer 對象的數據和狀態信息從屏幕的內容呈現中解耦出來。這種解耦爲 Core Animation 提供了一種方式插入到自身,並以動畫的形式展示狀態值的變動。例如,修改 layer 的position 屬性會致使 Core Animation 把 layer 從當前位置移動到新的位置。其餘屬性的修改也會產生相似的動畫。圖 1-2 展現了幾種你能夠在 layer 中表現的動畫類型。在 Animatable Properties中列出了能夠觸發動畫的 layer 屬性。性能

Figure 1-2 Examples of animations you can perform on layers
測試

在一次動畫期間,Core Animation 在硬件上爲你繪製了全部的圖形框架。你所須要作的只是明確動畫的起始點。一樣地你也能夠能夠根據須要自定義動畫的參數和時間,若是你沒有自定義這些參數和時間,Core Animation 會提供合適的缺省值。優化

怎麼初始化、配置動畫參數的信息,詳見 Animating Layer Content

Layer Objects Define Their Own Geometry

layer的其中一項工做就是根據其內容管理視覺幾何圖形。可視幾何圖形包括各類信息,諸如內容的 bounds、在屏幕上的 position,以及layer是否已經發生旋轉、縮放、變形。像視圖同樣,layer 也有能夠用來定位和展示內容的 frame、bounds。layer 也有一些視圖不具備的屬性,像定義操做發生點的 anchor point。一些列舉 layer 幾何圖形的方面是明顯不一樣於視圖的。

Layers Use Two Types of Coordinate Systems

layer 利用 point-based coordinate systmes(基於點的座標系統)和unit coordinate systems(單元座標系統)明確內容的放置。座標系統的使用依據被傳遞的信息類型。Point-based 座標在有明確的屏幕座標值或被明確地關聯到另個一 layer 時使用,例如 layer 的 position 屬性。Unit 座標在屬性值和屏幕座標無關聯但和其餘有關聯時使用,例如,layer 的 anchorPoint 座標,它指出了一個和 layer 自身的bounds關聯且能夠修改的點。

point-based 座標大多數時候經過 layer 的 bounds 和 position 屬性明確 layer 的 size 和 position。bounds 定義了 layer 的座標系統,包含 layer 在屏幕上的尺寸。position 屬性定義了layer相對於父層座標系統的定位。儘管 layer 有 frame 屬性,其實 frame 源於 bounds 和 position 兩個屬性,使用的頻次不高。

layer 的 bounds 和 frame 方向和平臺的默認方向相匹配。圖 1-3 展現了bounds 和 frame 在 ios 和 os x上的默認方向。ios中,bounds的原點方向默認在 layer 左上角,而 os x 中默認在左下角。若是你在 ios 和 os x 之間共享 Core Animation 的相關代碼,須要注意兩個平臺的這點差別。

Figure 1- 3 The default layer geometries for iOS and OS X

在圖 1-3 中須要注意一點,position 屬性被定位在 layer 的正中間,這個屬性值的明顯變化是衆多基於 layer 的 anchorPoint 屬性值之一。錨點表明肯定的座標原點的點,在 Achor Points Affect Geometric Manipulations 中有詳細的概述。

錨點是衆多使用 unit 座標系統來肯定屬性值的屬性之一。在 layer 的 size 屬性改變時會影響一些屬性的改變,unit 座標系統在Core Animation 中就是用來表明這些屬性的。你能夠認爲 unit 座標就是可能值的具體百分比。在 unit 座標控件中每個座標的範圍是 0.0~1.0 。例如,在 x 軸方向上,左邊距的座標是 0.0,右邊距則是 1.0 。在 y 軸方向上,unit 座標值的變化取決於平臺,若是 1-4 所示。
Figure 1-4 The default unit coordinate system for iOS and OS X


注意:在 OS X 10.8以前,geometryFlipped 屬性能夠在須要的時候修改 y 軸的默認方向。當 layer 包含翻轉變化時layer就須要這個屬性來修改方向。例如,若是父視圖使用了翻轉變形,它的子視圖(他們相關的layer)將經常被倒置,在這時 設置子視圖們的 geometryFlipped 屬性爲 YES 將是組簡單的解決方式。OS X 10.8 和以後的系統中,AppKit 爲你管理這個屬性。對於 iOS 應用,最好不要使用這個屬性。


全部的座標值,不管是座標點仍是 unit 座標都是浮點數。浮點數的使用能夠指出可能介於正常的座標值之間位置的精確值,並且還很方便,尤爲是打印時或者繪製一個點表明多個像素的 Retina 顯示時。浮點數的使用可讓你忽略對設備展現的依賴,僅僅須要指出你想要的精度值便可。

Anchor Points Affect Geometric Manipulations

你能夠用 layer 的 achorPoint 屬性來操控 layer 的集合形狀。最值得注意的是錨點的改變會影響到 position 或 transform 屬性的操做。position 屬性老是依賴於layer 的錨點來明確,而任何你應用的變形也取決於相關的錨點。

圖 1-5 說明了錨點從默認值改變爲另外一值時對 layer 的position 屬性的影響,儘管 layer 沒有在父層的 bounds 中並無移動,從 layer 的中心移動錨點紙 layer 的 bounds 原點改變了 position 屬性值。

圖 1-5 How the anchor point affects the layer's position property

圖 1-6 展現了原點的變化怎樣影響應用在 layer 上的變形。當你在 layer 上應用旋轉變形時,旋轉是以錨點爲中心。由於錨點默認被設置在 layer 的中間,此時能夠產生你所指望的旋轉形態,然而更改了毛點後,旋轉的結果就不一樣了。

圖 1-6 How the anchor point affects layer transformations

Layers Can Be Manipulated in Three Dimensions

每個 layer 都有兩個 transform 矩陣,你能夠用來操控 layer 和它的內容。CALayer 的 transform 屬性指出了你想應用在 layer 和它內嵌的子 layer形態。通常在你想修改 layer 自身時用這個屬性。例如,你能夠用此屬性等比例縮放或旋轉 layer 或 改變 暫時性地改變 position。sublayerTransform 屬性定義了額外的變形,僅僅用在子 layer 中,經常用來往圖形內容中單獨添加可見視覺現象。

Transform 依靠數值矩陣的多個座標值得到新的座標集,此作標記表明原點變形後的版本。Core Animation 的值能夠在三維中指出,因此每一個座標點有四個值,能夠用 4x4的矩陣標示,如圖 1-7 。圖形中的 transform 對應 CATransform3D 類型。幸運的是你不用直接修改這個結構的字段來造成一個變形,Core Animation提供綜合的方法集來建立 scale, translation和 rotation 矩陣,並且能夠作矩陣比較。另外關於方法操做變形,Core Animation 用鍵值對的編碼,支持直接用鍵值改變變形。你能夠修改的鍵列表,詳見 CATransform3D Key Paths

圖 1-7 Converting a coordinate using matrix math

圖 1-8 顯示了通常變形中你會用到的矩陣配置。身份座標值和其餘座標值的乘積返回的仍是一樣的座標。其餘的變形中座標怎麼被修改徹底依賴矩陣元素的改變。例如,沿着X軸移動,你只須要爲矩陣中的 tx 元素提供一個非零的數值,把 ty 和 tz 的值設爲 0 便可。再好比旋轉,你提供旋轉角度的正弦、餘弦值就好了。

圖 1-8 Matrix configurations for common transformations

你能夠建立和操做變形的相關方法,詳見 Core Animation Function Reference

Layer Trees Reflect Different Aspects of the Animation State

一個 app 在使用 Core Animation 時有三個 layer 對象集。當 app 的內容在屏幕顯示時每一 layer 對象集都扮演着不一樣的角色:

  • layer 模型樹對象(或簡稱 layer 樹)是你的 app 中交互最多的。其中的對象屬於模型對象,用來儲存動畫相關的目標值。在你改變一個 layer 的屬性時使用的就是這些對象。
  • presentation 樹對象包含的是動畫在執行中的狀態值。其中的目標值表明的時當前動畫在屏幕上呈現的當前值。你能夠用這些對象讀取當前動畫值可是別修改。
  • render 樹對象是 Core Animation 私有的,專門變現實際的動畫。

每個 layer 對象集在 app 中都是像視圖同樣以層次結構組織起來的。事實上在 app 的全部視圖中,有效的 layer 在初始時是何視圖的層次機構相匹配的。app 能夠根據需求添加額外的 layer 對象到已有的 layer 層次中(layer 和 view 是不相關的),當對一個視圖的最頂層不須要的內容就行性能優化時你可能會用到。圖 1-9 展現了 layer 在一個簡單 ios app 中的分解。示例中的 window 包含內容視圖,內容視圖包含一個 button 視圖和兩個單獨的 layer 對象,每個視圖都有相關的 layer 對象,它們一塊兒構成了 layer 的層次。

圖 1-9 Layers associated with a window

如圖 1-10,對於每個 layer 樹的對象,presentation 和 render 樹對象是一一對應的。正如以前提到的,app 主要用 layer 樹中的對象工做,有時會訪問 presentation 樹的對象。使用 layer 樹的對象 presentationLayer 能夠得到 presentation 樹相關的對象。當動畫進行時你可能會想得到屬性的相關值,訪問這個對象便可。

圖 1-10 The layer trees for a window


重要提示:你只能在動畫進行時訪問 presentation 樹的對象。在動畫的進行過程當中,presentation 樹包含 layer 顯示在屏幕上那一瞬間的各類值。這種行爲和 layer 樹相比是徹底不一樣的,layer 樹老是反應你代碼的最終值,也就是動畫最終的狀態。


The Relationship Between Layers and Views

layer 並非你 app 中視圖的替代,你不能在一個單獨的 layer 對象上構建一個可視界面。Layer 能夠爲你的視圖提供基礎設施。最明確的一點就是 layer 能夠提升視圖內容的繪製和動畫的效率和框架率。可是還有一些其它的 layer 完不成,不能處理事件,繪製內容,成爲響應鏈的一環,或者其它的一些事情。所以每個 app 必需要有一個或多個視圖來處理這類的交互。

在 iOS 中,每個視圖都是構建在一個相關的 layer 對象之上,在 OS X 中須要你手動決定哪一個視圖應該有 layer。在 OS X v10.8 及以後的版本中,爲全部視圖添加 layer 是比較合情理的,可是這也不是必須的,你仍然能夠爲那些不合理的視圖內容禁用 layer。Layer 的使用確實會增長 app 的內存使用,可是它的使用利大於弊,因此在禁用 layer 時最好測試一下 app 的性能。

當你開啓 layer 對一個視圖的支持時,此視圖就被做爲一個 layer-backed 視圖。在 layer-backed 視圖中,系統負責建立視圖之下的 layer,保持視圖和 layer 之間的同步。全部的 iOS 視圖都是 layer-backed 視圖,OS X 大部分視圖是。可是在 OS X 中你能夠建立一個 layer-hosting 視圖,一個你爲其提供 layer 對象的視圖。關於 layer-hosting 視圖,AppKit 提供了 layer 方便的管理方式,不用在視圖的響應變換時修改它。


注意:對於 layer-backed 視圖,強烈建議你儘量的管理視圖而不是它的 layer。在 iOS 中,視圖僅僅是對 layer object的封裝,所以你對 layer 的操做通常都會正常運行。可是不管是 ios 仍是 os x,都出現過用修改 layer 代替視圖修改時發生錯誤的情況。本文檔會盡量的指出這些誤區。


儘管 layer 和視圖有關聯,你仍然能夠建立一個和視圖不相關的 layer 對象。你能夠把這個單獨的 layer 對象嵌入到其餘的 layer 對象中,而後把他們和一個視圖相關聯。在性能優化時通常會採用此方法。例如,若是你想在多個地方使用同一張圖片,你能夠只加載一次這張圖片,把它和幾個單獨的 layer 對象相關聯,而後把他們加入到 layer 樹中,那麼每一個 layer 都會引用它,而不是從新 copy 到內存中。

怎麼在 app 中爲視圖啓用 layer,詳見 Enabling Core Animation Support in Your App。關於怎麼建立 layer 對象層和其餘的提示,詳見 Building a Layer Hierarchy

相關文章
相關標籤/搜索