Core Animation 爲你的 app 提供視圖和其餘視覺元素的通常動畫建立。Core Animation 並非替代你 app 的視圖,它是一種集成在視圖中爲視圖內容提供更好性能和支持的動畫技術。它經過緩存視圖內容到位圖實現,能夠直接地被圖形硬件操做。有時這種緩存行爲須要你屢次考慮怎麼呈現和管理你 app 的內容,可是多數時候你使用 Core Animation 並不須要知道這種緩存技術。除了緩存視圖內容,Core Animation也定義一種方式來明確任意的視圖內容,並集成此內容到你的視圖中和其餘的一塊兒表現動畫。html
你用 Core Animation 把 app 視圖和可視對象的變化用動畫的形式表現出來,大多數都是經過修改視圖的屬性,好比,你可能使用 Core Animation 更新視圖的position,size或者 opacity。Core Animation 根據你指定的屬性值和現有值的不一樣造成動畫。你不須要想卡通動畫那樣每秒60次的替換視圖內容,只須要在屏幕中移動視圖、淡入淡出視圖內容,應用任意的圖形形態到視圖,或者改變視圖的可視屬性。ios
Layer 對象 是在3D空間中組織成的2D界面,是Core Animation 的核心。像視圖同樣,layer 管理着幾何、內容和界面的可視屬性之類的信息。不一樣於視圖的地方是它並不定義本身的形態。一個 Layer 僅僅管理圍繞着位圖的狀態信息。位圖自己既能夠是視圖的最終繪製形態,也能夠是一張你指定的圖片。所以,你在 app 中使用的核心 layer 主要管理的是數據,能夠當作數據模型。這一點須要謹記,它會影響到動畫的效果。緩存
在你的 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 對象的數據和狀態信息從屏幕的內容呈現中解耦出來。這種解耦爲 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的其中一項工做就是根據其內容管理視覺幾何圖形。可視幾何圖形包括各類信息,諸如內容的 bounds、在屏幕上的 position,以及layer是否已經發生旋轉、縮放、變形。像視圖同樣,layer 也有能夠用來定位和展示內容的 frame、bounds。layer 也有一些視圖不具備的屬性,像定義操做發生點的 anchor point。一些列舉 layer 幾何圖形的方面是明顯不一樣於視圖的。
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 顯示時。浮點數的使用可讓你忽略對設備展現的依賴,僅僅須要指出你想要的精度值便可。
你能夠用 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
每個 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
一個 app 在使用 Core Animation 時有三個 layer 對象集。當 app 的內容在屏幕顯示時每一 layer 對象集都扮演着不一樣的角色:
每個 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 樹老是反應你代碼的最終值,也就是動畫最終的狀態。
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。