CoreAnimation的介紹



關於Core Animation
 
Core Animation是iOS與OS X平臺上負責圖形渲染與動畫的基礎設施。Core Animation可以動畫視圖和其他的可視元素。Core Animation爲你完成了實現動畫所需的大部分繪幀工作。你只需在配置少量的動畫參數(如開始點位置和結束點位置)就可啓動Core Animation。Core Animation將大部分實際的繪圖任務交給了圖形硬件處理,圖形硬件會加速圖形渲染的速度。這種自動化的圖形加速讓動畫具有更高的幀率且更加平滑,但這並不會增加CPU的負擔而導致影響你應用的運行速度。
 
如果你正在開發一個iOS應用,你就已經使用到了Core Animation;如果你開發的是OS X應用,你僅需小小的付出就可以利用Core Animation的強大功能。如下圖,Core Animation位於AppKit和UIKit的底層。它被緊密的集成到了Cocoa和Cocoa Touch視圖工作流中。雖然被緊密的集成,Core Animation也存在擴展功能的接口,這些接口暴露給了應用的視圖。使用這些接口能讓你更細粒度地控制應用中的動畫。
簡介
你可能從不需要直接使用Core Animation,但是當你使用Core Animation,你應該瞭解Core Animation是你app基礎設施中的一部分。
 
Core Animation管理着你的應用內容
Core Animation自身並不是一個繪圖系統。它只是一個負責在硬件上合成和操縱應用內容的基礎構件。Core Animation的核心是圖層對象,圖層對象用於管理和操控你的應用內容。圖層將捕獲的內容放到一副位圖中,圖形硬件能夠非常容易的操控你的位圖。在大部分應用中,圖層被作爲一種管理視圖內容的方式,但是你也可以創建標準的圖層,這取決於你自身的需要。
 
更改圖層屬性會產生動畫
你使用Core Animation創建的大部分動畫都包含對圖層屬性的更改。像視圖一樣,圖層對象也具有邊框矩形、座標原點、尺寸、不透明度、變換矩陣以及許多其他面向可視的屬性(如backgroundColor)。大部分這些屬性的值發生了變化都將會觸發隱式動畫被創建。隱式動畫是一種從舊屬性值動畫到新屬性值的動畫形式。如果需要全面掌控動畫行爲,你可以考慮使用顯式動畫這些屬性。
 
有組織的圖層層級
有組織的圖層之間存在着父子關係。圖層的組織會影響到圖層的可見內容。可見內容的管理與視圖的管理方法相似。附到視圖上的圖層集合的層級鏡像對應的視圖層級。你可以將獨立圖層添加到圖層的層級以擴充你的視圖的可視內容。
 
使用動作對象改變圖層的默認行爲
通過動作對象可以做到隱式的圖層動畫。動作對象是實現了一個預定義接口的常規對象。Core Animation使用動作對象實現與圖層關聯的常規的默認動畫集合。你可以創建屬於你自己的動作對象,以實現自定義的動畫或者實現其他行爲類型,然後你將動作對象賦值給圖層的某一屬性。當屬性發生變化,Core Animation檢索你的動作對象並告訴動作對象執行對應的動作。
 
如何使用該文檔
該文檔爲那些需要更全面的控制動畫效果或打算利用圖層提升繪圖性能的開發者。該文檔也介紹了iOS和OS X對圖層和視圖的合成。圖層和視圖的合成在iOS和OS X平臺上是不同的,理解這些不同對於創建高效的動畫至關重要。
 
預備知識
你應該瞭解你的目標平臺的視圖架構,以及熟悉如何創建基於視圖的動畫。如果你還未到該階段,請閱讀以下兩篇文檔:
 
對於iOS應用開發,你應該理解《iOS視圖編程指南》中關於視圖架構的描述。
對於OS X應用開發,你應該理解《視圖編程指南》中關於視圖架構的描述。
 
Core Animation基礎
 
Core Animation爲動畫視圖和其他可視元素提供了一個通用的系統。Core Animation並不是視圖的替代品,相反,它是一種和視圖相集成的技術。由於位圖可以直接由圖形硬件直接操控,通過將視圖的內容緩存到位圖中, 該技術可獲得更優的性能且支持動畫視圖內容。除了緩存視圖內容,Core Animation也定義了指定任意可視內容,然後將內容和視圖集成,最後動畫視圖和其他可視元素的方式。
 
使用Core Animation讓視圖和可視對象的變化能以動畫的形式呈現。大部分變化都與可視對象屬性的更改相關。比如Core Animation能讓視圖的位置、尺寸或者透明度的變化以動畫的形式呈現。當你更改了這些屬性的值, Core Animation在當前屬性值和最新指定的屬性值之間進行動畫。你一般不需要像卡通片那樣,完成每秒60次的視圖內容替換。相反,你應該利用Core Animation提供的移動視圖、淡入淡出視圖、對視圖應用任意的變換、改變視圖的其他可視屬性的方式完成動畫 。
 
圖層是繪圖與動畫的基礎
圖層對象是組織在三維空間的二維平面。它是使用Core Animation執行任何操作的核心構件。和視圖一樣,圖層的可管理信息包括幾何結構、內容、可視屬性;不同於視圖,圖層沒有定義它自己的外觀,圖層僅管理周圍位圖的狀態信息。位圖可以是視圖的繪圖結果或者一張圖片。因此主要的圖層被認爲是模型對象,因爲它們主要是用於管理數據。此概念務必記住,因爲它影響到動畫的行爲。
 
基於圖層的繪圖模型
大部分圖層不做實際的繪圖操作。相反,圖層捕獲應用的內容並緩存它們到位圖中。位圖有時也被稱爲儲備(backing store)。當你隨後改變了一個圖層的屬性值,你做的所有隻是改變了與圖層對象相關聯的狀態信息。當你的更改觸發了一個動畫,Core Animation傳遞圖層的位圖和圖層的狀態給圖形處理硬件。圖形處理器所做的工作是使用獲得的信息渲染位圖,如圖1-1所示,用圖形處理硬件操縱位圖要比圖形處理軟件能獲得更高的動畫效果。
因爲操縱的是靜態的位圖,基於圖層的繪圖和基於視圖的繪圖在技術上有明顯的不同。對基於視圖的繪圖,對視圖的改變經常會觸發調用視圖的drawRect:方法以重繪視圖內容。但是此種方式的代價相對較高,因爲它是CPU在主線程上的操作。Core Animation通過儘可能的使用圖形硬件操縱緩存後的位圖來避免了這種開銷,從而完成相同或相似的效果。
 
雖然Core Animation儘可能的使用緩存後的內容,但也必須提供初始內容並不時地更新它。
 
基於圖層的動畫
圖層的數據和狀態信息是從圖層內容的可視呈現中被分離了出來的。這種分離性給了Core Animation介入以及從舊的屬性值動畫到新的屬性值的機會。例如改變一個圖層的position屬性會引起Core Animation將圖層從當前的位置移動到新的具體位置。對其他屬性做相似的改變將引起適當的動畫效果。圖1-2展示了一些可以執行在圖層上的動畫類型。
圖1-2 可在圖層上執行的動畫類型
 
在動畫運行期間,Core Animation使用硬件幫你完成每一幀的繪製工作。你只需要指定動畫的開始點和結束點,剩下的交由Core Animation完成。如若需要,你也可以指定自定義時間信息和動畫參數,如果你沒有指定, Core Animation會提供適當的默認值。
 
圖層對象定義了自己的幾何結構
圖層的其中一項任務就是管理自身內容的可視幾何。可視幾何包含關於圖層內容邊界、在屏幕上的位置,是否圖層已被旋轉、縮放,或應用了某種變換。與視圖類似,一個圖層有一個frame和bound屬性,你可以使用這兩個屬性來定位圖層和它的內容。圖層也有一些視圖所沒有的屬性,比如anchor屬性,任何變換操作都是圍繞該點運轉的(可以理解爲一個按在圖層上的圖釘)。圖層的某些幾何概念的指定方式與視圖信息的指定方式也有不同。
 
圖層使用兩種類型的座標系統
圖層利用基於點的座標系統和單位座標系統指定內容的佈局。座標系統的選擇依賴於被傳達的信息類型。當指定的值是直接映射到屏幕或相對於其他圖層的座標,比如圖層的position屬性,則使用基於點的座標系統。當指定的值是相對於一些其他的值,與屏幕座標不相關聯,則使用單位座標。比如圖層的anchorPoint屬性,anchorPoint屬性指定了相對於圖層邊界的一個點。anchorPoint屬性可以更改。
 
基於點的座標最常用於指定圖層的尺寸和位置。可通過圖層的bounds和postion屬性設定圖層的尺寸和位置。bound定義了圖層自身的座標系統幷包含圖層在屏幕上的尺寸。position屬性定義了圖層相對於父座標系統的位置。雖然圖層有一個frame屬性,該屬性實際上是從bounds和position屬性派生而來,極少被使用。
 
圖層的bounds和frame矩形的方向始終與底層平臺的默認方向相匹配。圖1-3顯示了iOS和OS X平臺上邊界矩形的默認方向。在iOS中,默認情況下邊界矩形的原點在圖層的左上角。而OS X上邊界矩形的原點則在左下角。如果你在iOS和OS X版本的app之間共享Core Animation代碼,一定要對此種情況做區別對待。
圖1-3 iOS與OS X平臺默認的圖層幾何結構
 
注意到圖1-3中position屬性被定位在圖層的中間位置。position屬性的變化參照圖層的anchorPoint屬性。
 
錨點是使用單位座標系統的屬性之一。Core Animation中使用單位座標表示的屬性值可能會因爲圖層的尺寸變化而發生改變。你可以把單位座標當做是總數的百分比。在單位座標系統空間中每一個座標的取值範圍在0.0和1.0之間。比如說,沿着x軸,左側是0.0,右側是1.0.沿着y軸,單位座標值方向的不同依賴於具體的平臺。如圖1-4所示。
圖1-4 iOS和OS X平臺默認的單位座標系統
 
注意:直到OS X 10.8纔出現了geometryFlipped屬性,該屬性可以改變默認圖層y座標的方向。當翻轉變換被調用時,使用該屬性來調整圖層的方向有的時候是必需的。如果父視圖使用了翻轉變換,它的子視圖內容(以及它對應的圖層)將經常被顛倒。在這種情況下,設置子圖層的geometryFlipped屬性爲YES是一種修正該問題最簡單的方法。在OS X 10.8及以上版本,AppKit負責管理該屬性,你不應該更改它。對於iOS app,不推薦使用geometryFlipped屬性。
 
所有的座標值,無論是點還是單位座標都以浮點數指定。使用浮點數允許你更精確的指定可能落在整數座標值之間的點。特別是打印或向retina屏幕繪圖,浮點值都會很方便。浮點值允許你忽略底層設備的分辨率,而你只需要指定值的精度。
 
錨點影響幾何結構的操作
圖層的幾何操是相對於圖層的錨點進行的,anchorPoint屬性可以訪問圖層的錨點值。當改變圖層的postion和transform屬性值,錨點的影響就很明顯。position屬性是相對於圖層的錨點被指定。並且任何你對圖層陰影的變換操作也是相對於錨點。
 
圖1-5說明了改變錨點對圖層position屬性的影響。儘管圖層沒有在它的父邊界內移動,將錨點從中心點移動到圖層邊界的原點將改變position屬性值。
 
圖1-5 錨點是如何影響圖層的position屬性
 
圖1-6顯示了錨點的變化是如何影響到應用在圖層上的變換。當你對圖層應用了一個旋轉變換,圖層將圍繞中心點旋轉。因爲默認情況下,錨點被設定在圖層的中心位置。一般創建這類旋轉行爲正是你所期望的。然而如果你改變了錨點值,旋轉的結果也會發生變化。
圖1-6 錨點是如何影響圖層的變換
 
圖層可在三維空間中操作
圖層有兩個操控圖層和內容的變換矩陣,transform和sublayerTransform屬性。CALayer的transform屬性用來指定應用到圖層和它內嵌的子層上的變換。通常當你想更改圖層本身則使用該屬性。比方說,你可能使用該屬性縮放或旋轉圖層,或是臨時的改變圖層的位置。sublayerTransform屬性定義了僅應用在子層上的變換以及給場景內容添加透視效果。
 
變換行爲由多個座標確定,這些座標通過一個數字矩陣來獲取,獲取的座標結果是原始點被變換後的版本。因爲Core Animation的值可在三維空間中指定,每個座標點有四個值,這四個值需要和一個4*4的矩陣相乘。
 
如圖1-7所示。在Core Animation中,圖中的變換由CATransform3D類型表示。幸運的是,你不需要直接更改這個結構中的域值來執行標準變換。Core Animation爲創建縮放、平移、旋轉矩陣以及矩陣比較提供了綜合的函數集。除了使用函數操縱變換。Core Animation擴展了鍵值編碼以支持你使用鍵路徑更改一個變換操作。
圖1-7 使用矩陣數學轉換一個座標
 
圖1-8顯示了對一些常見的變換矩的配置。任何座標與單位矩陣相乘將返回完全相同的座標。座標如何被更改完全依賴於你變化的矩陣因子。比如,爲了僅在X軸上平移,你只需對變換矩陣的tx因子應用一個非零值,並讓ty和tz值爲0。如果是旋轉,應用一個旋轉角度的正弦和餘弦值。
圖1-8 常見變換的矩陣配置
 
不同的圖層樹反映了不同的動畫狀態
使用Core Animation的app擁有三個圖層對象集合。每一個圖層對象集合在呈現app內容上都扮演着不同的角色。
 
Ø模型圖層樹中的對象(或簡稱“圖層樹”)用的最多。在這個樹中的對象是模型對象,模型對象負責存儲所有動畫的目標值。無論何時改變圖層的屬性值,你使用的始終是某一個模型對象。
 
Ø呈現樹中的對象包含所有運行中的動畫的瞬時值。圖層樹對象包含的是動畫的目標值,而呈現樹中的對象代表顯示在屏幕上動畫的當前值。你不應該更改這個樹中的對象。相反,你使用這些對象來讀取當前動畫的值,可能用於創建開始於這些值的新的動畫。
 
Ø在渲染樹中的對象執行實際的動畫,並且對Core Animation是不公開的。
 
每一個圖層對象集合被組織在一個層次結構中,類似於app中的視圖。事實上,在一個所有視圖都支持圖層功能的app來說,每一個樹的初始結構完全與圖層的層次相匹配。一個app可以添加另外的圖層對象,因此圖層與視圖是不相關聯的。可以按照需求將圖層對象插入到指定的視圖層級中。你可能爲了優化app內容的性能而選擇加入圖層對象而非視圖,原因在於圖層的開銷要比視圖低。圖1-9展示了出現在一個簡單iOS app的圖層分解圖。在示例中窗口包含了一個內容視圖,內容視圖包含了一個按鈕視圖和兩個獨立的圖層對象。每一個視圖擁有一個相對應的構成圖層層次的圖層對象。
圖1-9 與窗口相關聯的圖層
在圖層樹中的每一個對象,在渲染樹和呈現樹中也存在一個與之匹配的對象。如圖1-10所示。正如之前提到過的,app主要與圖層樹中的對象進行交互,但可能有時會訪問呈現樹中的對象。具體地,訪問圖層樹中對象的presentationLayer屬性將返回一個在呈現樹中相對應的對象。你可能會通過該對象獲取在動畫執行過程中的某一時刻的屬性值。
圖1-10 窗口中的圖層樹
 
重要:只在動畫運行時訪問呈現樹中的對象。當動畫在進行中,呈現樹就包含了圖層顯示在屏幕上的那一刻的值。該行爲與圖層樹不同,圖層樹永遠只表示最終的目標值。
 
圖層不是視圖的替代品。因此無法創建一個基於單一圖層對象的可視界面。圖層是視圖的基礎設施。具體地,圖層讓視圖的繪圖和動畫更簡單和高效,並且能在繪圖和動畫時保持高幀率。然而許多事情圖層無法做到。圖層不能處理事件、繪製內容,特別是在響應鏈中,或是做一些其他的事情。因此,每個app必須有一個或多個視圖來處理這類交互。
 
在iOS中,每一個視圖有一個相對應的圖層對象。但在OS X中,你必須決定哪一個視圖擁有圖層。OS X 10.8以及之前的版本中,添加圖層到所有視圖上也許是有意義的。然而你不必這樣做,你仍可以關閉圖層防止不必要以及無根據的開銷。
 
圖層在某種程度上減少了程序的內存開銷,圖層的這些優點遠遠超出它的缺點。所以最好是在禁用圖層支持之前測試你app的性能。
 
當你的視圖支持圖層後,此時該視圖被稱爲layer-backed視圖。對於layer-backed視圖,系統負責創建底層的圖層對象,並保持與視圖的同步。所以iOS視圖都是支持圖層的並且在OS X中的大部分視圖也是如此。但是在OS X中,你也可以創建圖層託管(layer-hosting view)視圖,該視圖的圖層對象由你來提供。
 
注意:對於layer-backed視圖,建議只操作視圖而不是圖層。iOS中視圖僅僅是對圖層對象的精簡包裝,所以任何你對圖層的操作通常都會正常工作。但是iOS和OS X平臺上操縱圖層而不是圖層可能不會取得預期的結果。該文檔會儘可能的指出這些陷阱並提供一種方式讓你可以與它們工作。
 
除了與視圖相關的圖層,你也可以創建獨立的圖層對象。你可以嵌入這些獨立圖層對象到任何其他圖層對象中,包括與視圖相關的圖層。你一般使用圖層對象作爲具體優化方法的一部分。比如說,如果你想使用相同的圖片在多個地方,你可以只加載圖片一次,然後將圖片和多個獨立的圖層對象相關聯,最後添加這些圖層對象到圖層樹中。每一個圖層只會引用源圖片而不是嘗試在內存中創建自身對圖片的拷貝。
關於Core Animation
 
Core Animation是iOS與OS X平臺上負責圖形渲染與動畫的基礎設施。Core Animation可以動畫視圖和其他的可視元素。Core Animation爲你完成了實現動畫所需的大部分繪幀工作。你只需在配置少量的動畫參數(如開始點位置和結束點位置)就可啓動Core Animation。Core Animation將大部分實際的繪圖任務交給了圖形硬件處理,圖形硬件會加速圖形渲染的速度。這種自動化的圖形加速讓動畫具有更高的幀率且更加平滑,但這並不會增加CPU的負擔而導致影響你應用的運行速度。
 
如果你正在開發一個iOS應用,你就已經使用到了Core Animation;如果你開發的是OS X應用,你僅需小小的付出就可以利用Core Animation的強大功能。如下圖,Core Animation位於AppKit和UIKit的底層。它被緊密的集成到了Cocoa和Cocoa Touch視圖工作流中。雖然被緊密的集成,Core Animation也存在擴展功能的接口,這些接口暴露給了應用的視圖。使用這些接口能讓你更細粒度地控制應用中的動畫。
簡介
你可能從不需要直接使用Core Animation,但是當你使用Core Animation,你應該瞭解Core Animation是你app基礎設施中的一部分。
 
Core Animation管理着你的應用內容
Core Animation自身並不是一個繪圖系統。它只是一個負責在硬件上合成和操縱應用內容的基礎構件。Core Animation的核心是圖層對象,圖層對象用於管理和操控你的應用內容。圖層將捕獲的內容放到一副位圖中,圖形硬件能夠非常容易的操控你的位圖。在大部分應用中,圖層被作爲一種管理視圖內容的方式,但是你也可以創建標準的圖層,這取決於你自身的需要。
 
更改圖層屬性會產生動畫
你使用Core Animation創建的大部分動畫都包含對圖層屬性的更改。像視圖一樣,圖層對象也具有邊框矩形、座標原點、尺寸、不透明度、變換矩陣以及許多其他面向可視的屬性(如backgroundColor)。大部分這些屬性的值發生了變化都將會觸發隱式動畫被創建。隱式動畫是一種從舊屬性值動畫到新屬性值的動畫形式。如果需要全面掌控動畫行爲,你可以考慮使用顯式動畫這些屬性。
 
有組織的圖層層級
有組織的圖層之間存在着父子關係。圖層的組織會影響到圖層的可見內容。可見內容的管理與視圖的管理方法相似。附到視圖上的圖層集合的層級鏡像對應的視圖層級。你可以將獨立圖層添加到圖層的層級以擴充你的視圖的可視內容。
 
使用動作對象改變圖層的默認行爲
通過動作對象可以做到隱式的圖層動畫。動作對象是實現了一個預定義接口的常規對象。Core Animation使用動作對象實現與圖層關聯的常規的默認動畫集合。你可以創建屬於你自己的動作對象,以實現自定義的動畫或者實現其他行爲類型,然後你將動作對象賦值給圖層的某一屬性。當屬性發生變化,Core Animation檢索你的動作對象並告訴動作對象執行對應的動作。
 
如何使用該文檔
該文檔爲那些需要更全面的控制動畫效果或打算利用圖層提升繪圖性能的開發者。該文檔也介紹了iOS和OS X對圖層和視圖的合成。圖層和視圖的合成在iOS和OS X平臺上是不同的,理解這些不同對於創建高效的動畫至關重要。
 
預備知識
你應該瞭解你的目標平臺的視圖架構,以及熟悉如何創建基於視圖的動畫。如果你還未到該階段,請閱讀以下兩篇文檔:
 
對於iOS應用開發,你應該理解《iOS視圖編程指南》中關於視圖架構的描述。
對於OS X應用開發,你應該理解《視圖編程指南》中關於視圖架構的描述。
 
Core Animation基礎
 
Core Animation爲動畫視圖和其他可視元素提供了一個通用的系統。Core Animation並不是視圖的替代品,相反,它是一種和視圖相集成的技術。由於位圖可以直接由圖形硬件直接操控,通過將視圖的內容緩存到位圖中, 該技術可獲得更優的性能且支持動畫視圖內容。除了緩存視圖內容,Core Animation也定義了指定任意可視內容,然後將內容和視圖集成,最後動畫視圖和其他可視元素的方式。
 
使用Core Animation讓視圖和可視對象的變化能以動畫的形式呈現。大部分變化都與可視對象屬性的更改相關。比如Core Animation能讓視圖的位置、尺寸或者透明度的變化以動畫的形式呈現。當你更改了這些屬性的值, Core Animation在當前屬性值和最新指定的屬性值之間進行動畫。你一般不需要像卡通片那樣,完成每秒60次的視圖內容替換。相反,你應該利用Core Animation提供的移動視圖、淡入淡出視圖、對視圖應用任意的變換、改變視圖的其他可視屬性的方式完成動畫 。
 
圖層是繪圖與動畫的基礎
圖層對象是組織在三維空間的二維平面。它是使用Core Animation執行任何操作的核心構件。和視圖一樣,圖層的可管理信息包括幾何結構、內容、可視屬性;不同於視圖,圖層沒有定義它自己的外觀,圖層僅管理周圍位圖的狀態信息。位圖可以是視圖的繪圖結果或者一張圖片。因此主要的圖層被認爲是模型對象,因爲它們主要是用於管理數據。此概念務必記住,因爲它影響到動畫的行爲。
 
基於圖層的繪圖模型
大部分圖層不做實際的繪圖操作。相反,圖層捕獲應用的內容並緩存它們到位圖中。位圖有時也被稱爲儲備(backing store)。當你隨後改變了一個圖層的屬性值,你做的所有隻是改變了與圖層對象相關聯的狀態信息。當你的更改觸發了一個動畫,Core Animation傳遞圖層的位圖和圖層的狀態給圖形處理硬件。圖形處理器所做的工作是使用獲得的信息渲染位圖,如圖1-1所示,用圖形處理硬件操縱位圖要比圖形處理軟件能獲得更高的動畫效果。
因爲操縱的是靜態的位圖,基於圖層的繪圖和基於視圖的繪圖在技術上有明顯的不同。對基於視圖的繪圖,對視圖的改變經常會觸發調用視圖的drawRect:方法以重繪視圖內容。但是此種方式的代價相對較高,因爲它是CPU在主線程上的操作。Core Animation通過儘可能的使用圖形硬件操縱緩存後的位圖來避免了這種開銷,從而完成相同或相似的效果。
 
雖然Core Animation儘可能的使用緩存後的內容,但也必須提供初始內容並不時地更新它。
 
基於圖層的動畫
圖層的數據和狀態信息是從圖層內容的可視呈現中被分離了出來的。這種分離性給了Core Animation介入以及從舊的屬性值動畫到新的屬性值的機會。例如改變一個圖層的position屬性會引起Core Animation將圖層從當前的位置移動到新的具體位置。對其他屬性做相似的改變將引起適當的動畫效果。圖1-2展示了一些可以執行在圖層上的動畫類型。
圖1-2 可在圖層上執行的動畫類型
 
在動畫運行期間,Core Animation使用硬件幫你完成每一幀的繪製工作。你只需要指定動畫的開始點和結束點,剩下的交由Core Animation完成。如若需要,你也可以指定自定義時間信息和動畫參數,如果你沒有指定, Core Animation會提供適當的默認值。
 
圖層對象定義了自己的幾何結構
圖層的其中一項任務就是管理自身內容的可視幾何。可視幾何包含關於圖層內容邊界、在屏幕上的位置,是否圖層已被旋轉、縮放,或應用了某種變換。與視圖類似,一個圖層有一個frame和bound屬性,你可以使用這兩個屬性來定位圖層和它的內容。圖層也有一些視圖所沒有的屬性,比如anchor屬性,任何變換操作都是圍繞該點運轉的(可以理解爲一個按在圖層上的圖釘)。圖層的某些幾何概念的指定方式與視圖信息的指定方式也有不同。
 
圖層使用兩種類型的座標系統
圖層利用基於點的座標系統和單位座標系統指定內容的佈局。座標系統的選擇依賴於被傳達的信息類型。當指定的值是直接映射到屏幕或相對於其他圖層的座標,比如圖層的position屬性,則使用基於點的座標系統。當指定的值是相對於一些其他的值,與屏幕座標不相關聯,則使用單位座標。比如圖層的anchorPoint屬性,anchorPoint屬性指定了相對於圖層邊界的一個點。anchorPoint屬性可以更改。
 
基於點的座標最常用於指定圖層的尺寸和位置。可通過圖層的bounds和postion屬性設定圖層的尺寸和位置。bound定義了圖層自身的座標系統幷包含圖層在屏幕上的尺寸。position屬性定義了圖層相對於父座標系統的位置。雖然圖層有一個frame屬性,該屬性實際上是從bounds和position屬性派生而來,極少被使用。
 
圖層的bounds和frame矩形的方向始終與底層平臺的默認方向相匹配。圖1-3顯示了iOS和OS X平臺上邊界矩形的默認方向。在iOS中,默認情況下邊界矩形的原點在圖層的左上角。而OS X上邊界矩形的原點則在左下角。如果你在iOS和OS X版本的app之間共享Core Animation代碼,一定要對此種情況做區別對待。
圖1-3 iOS與OS X平臺默認的圖層幾何結構
 
注意到圖1-3中position屬性被定位在圖層的中間位置。position屬性的變化參照圖層的anchorPoint屬性。
 
錨點是使用單位座標系統的屬性之一。Core Animation中使用單位座標表示的屬性值可能會因爲圖層的尺寸變化而發生改變。你可以把單位座標當做是總數的百分比。在單位座標系統空間中每一個座標的取值範圍在0.0和1.0之間。比如說,沿着x軸,左側是0.0,右側是1.0.沿着y軸,單位座標值方向的不同依賴於具體的平臺。如圖1-4所示。
圖1-4 iOS和OS X平臺默認的單位座標系統
 
注意:直到OS X 10.8纔出現了geometryFlipped屬性,該屬性可以改變默認圖層y座標的方向。當翻轉變換被調用時,使用該屬性來調整圖層的方向有的時候是必需的。如果父視圖使用了翻轉變換,它的子視圖內容(以及它對應的圖層)將經常被顛倒。在這種情況下,設置子圖層的geometryFlipped屬性爲YES是一種修正該問題最簡單的方法。在OS X 10.8及以上版本,AppKit負責管理該屬性,你不應該更改它。對於iOS app,不推薦使用geometryFlipped屬性。
 
所有的座標值,無論是點還是單位座標都以浮點數指定。使用浮點數允許你更精確的指定可能落在整數座標值之間的點。特別是打印或向retina屏幕繪圖,浮點值都會很方便。浮點值允許你忽略底層設備的分辨率,而你只需要指定值的精度。
 
錨點影響幾何結構的操作
圖層的幾何操是相對於圖層的錨點進行的,anchorPoint屬性可以訪問圖層的錨點值。當改變圖層的postion和transform屬性值,錨點的影響就很明顯。position屬性是相對於圖層的錨點被指定。並且任何你對圖層陰影的變換操作也是相對於錨點。
 
圖1-5說明了改變錨點對圖層position屬性的影響。儘管圖層沒有在它的父邊界內移動,將錨點從中心點移動到圖層邊界的原點將改變position屬性值。
 
圖1-5 錨點是如何影響圖層的position屬性
 
圖1-6顯示了錨點的變化是如何影響到應用在圖層上的變換。當你對圖層應用了一個旋轉變換,圖層將圍繞中心點旋轉。因爲默認情況下,錨點被設定在圖層的中心位置。一般創建這類旋轉行爲正是你所期望的。然而如果你改變了錨點值,旋轉的結果也會發生變化。
圖1-6 錨點是如何影響圖層的變換
 
圖層可在三維空間中操作
圖層有兩個操控圖層和內容的變換矩陣,transform和sublayerTransform屬性。CALayer的transform屬性用來指定應用到圖層和它內嵌的子層上的變換。通常當你想更改圖層本身則使用該屬性。比方說,你可能使用該屬性縮放或旋轉圖層,或是臨時的改變圖層的位置。sublayerTransform屬性定義了僅應用在子層上的變換以及給場景內容添加透視效果。
 
變換行爲由多個座標確定,這些座標通過一個數字矩陣來獲取,獲取的座標結果是原始點被變換後的版本。因爲Core Animation的值可在三維空間中指定,每個座標點有四個值,這四個值需要和一個4*4的矩陣相乘。
 
如圖1-7所示。在Core Animation中,圖中的變換由CATransform3D類型表示。幸運的是,你不需要直接更改這個結構中的域值來執行標準變換。Core Animation爲創建縮放、平移、旋轉矩陣以及矩陣比較提供了綜合的函數集。除了使用函數操縱變換。Core Animation擴展了鍵值編碼以支持你使用鍵路徑更改一個變換操作。
圖1-7 使用矩陣數學轉換一個座標
 
圖1-8顯示了對一些常見的變換矩的配置。任何座標與單位矩陣相乘將返回完全相同的座標。座標如何被更改完全依賴於你變化的矩陣因子。比如,爲了僅在X軸上平移,你只需對變換矩陣的tx因子應用一個非零值,並讓ty和tz值爲0。如果是旋轉,應用一個旋轉角度的正弦和餘弦值。
圖1-8 常見變換的矩陣配置
 
不同的圖層樹反映了不同的動畫狀態
使用Core Animation的app擁有三個圖層對象集合。每一個圖層對象集合在呈現app內容上都扮演着不同的角色。
 
Ø模型圖層樹中的對象(或簡稱“圖層樹”)用的最多。在這個樹中的對象是模型對象,模型對象負責存儲所有動畫的目標值。無論何時改變圖層的屬性值,你使用的始終是某一個模型對象。
 
Ø呈現樹中的對象包含所有運行中的動畫的瞬時值。圖層樹對象包含的是動畫的目標值,而呈現樹中的對象代表顯示在屏幕上動畫的當前值。你不應該更改這個樹中的對象。相反,你使用這些對象來讀取當前動畫的值,可能用於創建開始於這些值的新的動畫。
 
Ø在渲染樹中的對象執行實際的動畫,並且對Core Animation是不公開的。
 
每一個圖層對象集合被組織在一個層次結構中,類似於app中的視圖。事實上,在一個所有視圖都支持圖層功能的app來說,每一個樹的初始結構完全與圖層的層次相匹配。一個app可以添加另外的圖層對象,因此圖層與視圖是不相關聯的。可以按照需求將圖層對象插入到指定的視圖層級中。你可能爲了優化app內容的性能而選擇加入圖層對象而非視圖,原因在於圖層的開銷要比視圖低。圖1-9展示了出現在一個簡單iOS app的圖層分解圖。在示例中窗口包含了一個內容視圖,內容視圖包含了一個按鈕視圖和兩個獨立的圖層對象。每一個視圖擁有一個相對應的構成圖層層次的圖層對象。
圖1-9 與窗口相關聯的圖層
在圖層樹中的每一個對象,在渲染樹和呈現樹中也存在一個與之匹配的對象。如圖1-10所示。正如之前提到過的,app主要與圖層樹中的對象進行交互,但可能有時會訪問呈現樹中的對象。具體地,訪問圖層樹中對象的presentationLayer屬性將返回一個在呈現樹中相對應的對象。你可能會通過該對象獲取在動畫執行過程中的某一時刻的屬性值。
圖1-10 窗口中的圖層樹
 
重要:只在動畫運行時訪問呈現樹中的對象。當動畫在進行中,呈現樹就包含了圖層顯示在屏幕上的那一刻的值。該行爲與圖層樹不同,圖層樹永遠只表示最終的目標值。
 
圖層不是視圖的替代品。因此無法創建一個基於單一圖層對象的可視界面。圖層是視圖的基礎設施。具體地,圖層讓視圖的繪圖和動畫更簡單和高效,並且能在繪圖和動畫時保持高幀率。然而許多事情圖層無法做到。圖層不能處理事件、繪製內容,特別是在響應鏈中,或是做一些其他的事情。因此,每個app必須有一個或多個視圖來處理這類交互。
 
在iOS中,每一個視圖有一個相對應的圖層對象。但在OS X中,你必須決定哪一個視圖擁有圖層。OS X 10.8以及之前的版本中,添加圖層到所有視圖上也許是有意義的。然而你不必這樣做,你仍可以關閉圖層防止不必要以及無根據的開銷。
 
圖層在某種程度上減少了程序的內存開銷,圖層的這些優點遠遠超出它的缺點。所以最好是在禁用圖層支持之前測試你app的性能。
 
當你的視圖支持圖層後,此時該視圖被稱爲layer-backed視圖。對於layer-backed視圖,系統負責創建底層的圖層對象,並保持與視圖的同步。所以iOS視圖都是支持圖層的並且在OS X中的大部分視圖也是如此。但是在OS X中,你也可以創建圖層託管(layer-hosting view)視圖,該視圖的圖層對象由你來提供。
 
注意:對於layer-backed視圖,建議只操作視圖而不是圖層。iOS中視圖僅僅是對圖層對象的精簡包裝,所以任何你對圖層的操作通常都會正常工作。但是iOS和OS X平臺上操縱圖層而不是圖層可能不會取得預期的結果。該文檔會儘可能的指出這些陷阱並提供一種方式讓你可以與它們工作。
 
除了與視圖相關的圖層,你也可以創建獨立的圖層對象。你可以嵌入這些獨立圖層對象到任何其他圖層對象中,包括與視圖相關的圖層。你一般使用圖層對象作爲具體優化方法的一部分。比如說,如果你想使用相同的圖片在多個地方,你可以只加載圖片一次,然後將圖片和多個獨立的圖層對象相關聯,最後添加這些圖層對象到圖層樹中。每一個圖層只會引用源圖片而不是嘗試在內存中創建自身對圖片的拷貝。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章