Core Animation 文檔翻譯 (第二篇)—核心動畫基礎要素

 


 

前言html

 

核心動畫爲咱們APP內Views動畫和其餘可視化元素動畫提供了綜合性的實現體系。核心動畫不是咱們APP內Views的替代品,相反,它是一種結合Views來提供更好性能和支持Content動畫的技術。它經過將Views的Content緩存進能夠被繪圖軟件直接操做處理的Bitmaps來達到這種高性能。在某些狀況下,這種緩存技術可能須要咱們從新思考咱們將要如何呈現和管理咱們的APP的Content,可是大多數狀況咱們能夠在不去考慮這種緩存帶來的影響而直接使用核心動畫。除了緩存View 的Content以外,核心動畫也定義了一種制定任意可視化Content,使咱們的Views與可視化Content結合起來,並使該可視化Content和其餘事物一塊兒動畫。編程

 咱們使用核心動畫讓咱們APP內Views和可視化對象特性的變動以動畫的形式過渡。許多可視化對象的變動和修改可視化對象的屬性有關聯,例如,咱們可能使用核心動畫來爲View的position、size、opacity的改變製做動畫。當咱們調整了相似的屬性,核心動畫將會製做在當前屬性值和咱們指定的新值之間過渡的動畫。咱們尤爲不該該使用核心動畫以60次每秒的頻率替換View的Content,例如不該該使用核心動畫以這種方式製做卡通片。相反,咱們使用核心動畫從屏幕上移除View的Content,漸隱漸出Content,任意調整Views的圖形transformation,或者改變View的其餘可視化屬性。緩存

 

Layers 提供繪畫和動畫的主要部分app

 

Layer 對象是2D平面,並被組織到3D空間;核心動畫能作的全部事情的核心也是Layer。和Views同樣,Layers管理他們各自的幾何、Content和其餘可視化屬性。和Views不同的是,Layers沒有定義顯示錶面。一個Layer僅僅管理一個bitmap相關的狀態信息;這個bitmap他自己多是一個View的繪製結果或者咱們制定的固定的圖片,由於Layers主要管理data,所以APP中咱們使用的大部分Layers被視爲模型對象。這個概念很重要,須要記住,由於它影響動畫的行爲ide

 

基於 Layer的繪製模型函數

 

APP中許多Layers沒有作任何實際繪製。相反,一個Layer捕獲咱們APP提供的Content並將他們緩存進一個bitmap中,這個bitmap有時候被稱做輔助存儲。當咱們接着改變Layer的屬性,全部咱們作的即是改變Layer對象相關聯的狀態信息。當一個改變出發一個動畫,核心動畫將Layer的bitmap和狀態信息傳遞給繪圖硬件,繪圖硬件使用這些新的信息渲染bitmap,Figure 1-1圖顯示的流程。在硬件中操做處理bitmap將會產生更快的動畫,相較於使用軟件。性能

                                                                     

 Figure 1-1  How Core Animation draws content測試

由於他操做處理一個靜態bitmap,基於Layer的繪製明顯不一樣於傳統的基於View的繪製技術。在基於View的繪製中,View的變化一般會調用該View的drawRect:方法 來使用新的參數繪製Content;可是這種方式的繪製的消耗是很高的,由於他是使用CPU在主線程上完成的。核心動畫經過一種流程避免這種高昂的消耗--當可以經過操做處理硬件內緩存的bitmap達到相同或類似的效應時候。優化

儘管核心動畫儘量的使用緩存的Content,咱們的APP仍舊提供這個初始化的Content和不時的更新Content。APP中有幾個方法爲經過Content提供Layer對象,在Providing a Layer’s Contents(後續有翻譯)中有詳細描述。動畫

 

 基於Layer的動畫

 

Layer對象的數據和狀態信息與屏幕上Layer的Content的可視化展示之間是解耦的。這種解耦使得核心動畫處於Layer對象與屏幕上可視化的展示之間,並可以使這個從舊狀態值到新狀態值的過渡顯示爲動畫。例如,改變一個Layer的position屬性會引發Layer從它當前position移動到新指定的position。其餘屬性的類似變動也會引發相應的動畫。Figure 1-2展示了幾個咱們可以在Layers上執行的動畫種類。Layer能夠觸發動畫的屬性,能夠參見Animatable Properties。(後續會有翻譯)

                                                             

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

 

在動畫的過程期間,核心動畫在硬件中作了全部的逐幀繪製。全部咱們應該作的僅僅是制定動畫的開始和結束點,並開啓核心動畫,核心動畫將會作剩下的工做。咱們也能制定自定義的必要的timing信息和動畫參數;然而,若是咱們沒有設定相應的默認值,核心動畫將會提供適當的默認值。

更多信息關於如何去開啓動畫和配置動畫參數參見Animating Layer Content。(後續會有翻譯)

 

Layer 對象定義他們的幾何形狀

 

Layer的功能之一就爲Layer自身的Content管理可視化幾何形狀。可視化幾何形狀所包含的信息:Content在屏幕上的bounds和position和該Layer是否經過任何途徑被旋轉、縮放、transformed。就像一個View,一個Layer也有frame和bounds屬性以用於調整該Layer和Content的位置。Layers也有其餘和View也有的屬性,例如anchor point(錨點),能夠圍繞錨點製做動畫的點。咱們指定一些Layer的幾何方面值與指定View相應的值是有區別的。

 

Layers 使用兩種座標系統

 

Layers 利用基於點的座標系統和單元座標系統指定Content的位置。具體使用哪一種座標系統取決於被傳遞的信息類型。當指定映射到屏幕座標值和被關聯到另外的Layer時候,這兩種狀況將會使用基於點的座標,例如Layer的position 屬性。當某些值不該該被綁定到屏幕座標系統時候(由於它是關聯一些其餘值的)會使用到單元座標系統。例如,Layer的anchorPoint屬性是指定和Layer自己的bounds相關聯的點,bounds會變,就會影響單元座標系統內anchorPoint。

基於點座標系統最廣泛的用途就是指定Layer的size 和position,其實就是指咱們使用Layer的bounds和position屬性。bounds 定義Layer自己內部座標系統幷包含Layer在屏幕上的size。position屬性定義了Layer在它父座標系統上的位置。儘管Layers有frame屬性,frame屬性其實是從bounds和position屬性獲得的,Layer的frame不經常使用。

Layer的bounds和frame的方向老是和所在的平臺默認方向匹配的。Figure 1-3展現了iOS和OS X兩個平臺的默認方向。在iOS裏面,原點的位置默認是左上角,在OS X平臺默認是左下角。若是咱們在兩個平臺之間分享核心動畫的代碼,咱們必須考慮二者的不一樣之處。

                                                       

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

在圖1-3中有件事情須要注意:position屬性是Layer的中心點。有幾個屬性的值是基於Layer的anchorPoint屬性,position就是其中之一。anchor point 表明了特定座標系統的起點,錨點被描述的更詳細在文檔Anchor Points Affect Geometric Manipulations。(後續會有翻譯)

有幾個屬性的值是咱們使用單元座標系統指定的,anchor point 就是其中之一。核心動畫使用單元座標系統表明屬性值,這些屬性值可能會發生變化當Layer的size改變的時候。咱們能夠把單元座標視爲一個總體值的百分比(例如寬度被設定爲爲100,錨點是50%)。在單元座標內,每一個座標值的變化範圍是0.0到1.0。例如沿着X軸,左邊緣是0.0,右邊緣是1.0。沿着Y軸單元座標的值的變化和所在平臺有關,如圖1-4所展現。

   

  Figure 1-4  The default unit coordinate systems for iOS and OS X

 

 

 注意:直到OS X 10.8,當有須要時,geometryFlipped屬性可以調整一個Layer的Y軸方向。當涉及到反轉transforms調整時,經過使用這個屬性來矯正Layer的方向是頗有必要的。例如若是父View使用一個反轉transform調整時,子Views的contents(和他們相應的Layers)將會被反轉。在這些狀況下,設置子Layers的geometryFlipped屬性爲YES是可以改正問題的一個簡單的方式。在OS X 10.8和以後,AppKit 管理這些屬性而且咱們不該該修改他。對於iOS APPs,徹底不建議使用geometryFlipped屬性。

全部的座標值,不管點座標仍是單元座標,它們都是浮點型數值,使用浮點型使咱們可以指定精細的位置,這些位置可能在標準座標值之間。浮點值的使用很便利,尤爲在印刷或者當會知道Retina屏幕時候,Retina屏幕的一個點可能表明多個像素。浮點值容許咱們忽略基於設備的分辨率,可直接調整到某個咱們想要的精確值。

 

Anchor Point 影響幾何圖形操做處理

 

Layer的幾何相關操做都受到Layer的anchor point的影響,即Layer的anchorPoint屬性。當調整position或transform屬性的時候,anchor point的影響會很明顯。position 屬性老是和Layer的anchor point關聯在一塊兒的;對Layer作的transformations調整也老是和anchor point 關聯着的。

圖1-5所描述了——Layer的anchor point 從默認值到一個新值的調整是如何影響position屬性的。anchor point從Layer的中心點移動到Layer的origin,改變了Layer的position屬性,可是Layer在他父Layer的bounds內座標沒有發生變化。

  Figure 1-5  How the anchor point affects the layer’s position property

 

 

圖1-6展示了anchor point的改變是如何影響Layer的transforms變換的。當咱們對Layer作旋轉transform調整時候,旋轉將會繞着anchor point發生。因爲anchor point默認在Layer的中心位置,正常的旋轉調整將會是圍繞Layer的中心發生;若是咱們改變anchor point,旋轉的結果將會發生變化。

 Figure 1-6  How the anchor point affects layer transformations 

 

 

Layer 的三維空間操做

 

每個Layer有兩個transform 矩陣,咱們可使用這兩個矩陣來操做處理Layer的contents。Layer的transform屬性指定的變換將會被應用到Layer自己和內嵌的sublayers。一般咱們想使用這個屬性來調整Layer自己,例如,咱們可能使用transform屬性來縮放或旋轉某個Layer,或者臨時調整Layer的position。sublayerTransform屬性定義的變換僅僅用來調整Layer的sublayers,在某些場景中它也一般備用來添加人眼視角效應。

Transforms 經過矩陣變換改變當前座標值獲得新的座標值(coordinate),新的座標值表明着轉換後的座標值。因爲核心動畫能夠指定三維空間變換,在矩陣變換中,每個點對應着一個4x4的矩陣。如圖1-7.在覈心動畫中transform表明着CATransform3D類型。幸運的是,咱們不須要直接修改這個4x4的矩陣來執行標準的轉換;核心動畫提供一個全面的函數集合,包含操做有scale,translation,rotation矩陣以及矩陣的比較。除了使用函數操做矩陣以外,核心動畫也擴展了KVC,以便於支持咱們使用key paths修改transform。能夠經過key paths修改的列表參見CATransform3D Key Paths

Figure 1-7  Converting a coordinate using matrix math


圖1-8展示了常見的transformations的矩陣配置。任何乘以identity矩陣的coordinate將不會變化,當乘以其餘矩陣時,coordinate的變化和矩陣每一個份量都有關。例如,沿着X軸平移,咱們須要提供非零的 tx 份量並讓 ty 和 tz 爲0。對於旋轉操做,咱們應該提供合適的 sine 和 cosine 值。

Figure 1-8  Matrix configurations for common transformations

 

關於可用的函數信息和矩陣操做,能夠參見Core Animation Function Reference。

 

 圖層(layer)樹反應動畫狀態的不一樣方面

 

使用核心動畫的APP有三種Layer對象集合;在將content顯示到屏幕上的任務中,每一個Layer對象集合扮演者不一樣的角色。

  ·模型樹(model layer tree 也被簡稱爲圖層樹)是和APP交互最多的。模型樹上面的模型對象保存着動畫的目標值。不管什麼時候咱們要改變一個Layer的屬性時,咱們應該使用model對象。

  ·呈現樹(presentation tree)包含着正在動畫過程當中的值。不管在哪裏模型樹總包含動畫的目標值(最終值),而渲染樹反映屏幕上顯示的當前值。咱們永遠都不要修改呈現樹上的對象,而能夠藉助呈現對象來讀取當前動畫的值,還能夠將該值做爲一個新的動畫的起點。

  ·渲染樹(render tree)內包含的對象執行真正的動畫,而且它是核心動畫私有的。

每個集合內的Layer對象都想APP內的Views同樣是以層級結構組織起來的。事實上,一個爲全部Views內嵌Layers的APP中,每一個(圖層)樹的結構和View的層級結構是一直的。然而,APP能夠添加單獨的Layer對象(單獨的Layer對象是指的沒有被關聯到view的層次中的),經過這麼作咱們能夠優化APP的content方面的性能,由於某些content的顯示是不須要使用Views的其餘功能的。圖1-9展現了Layer層次的分解圖。在這個例子中window包含一個content View,這個View包含了一個button View和兩個單獨的Layer對象。每個View包含一個對應的Layer對象,這個Layer對象用於造成Layer層結構的一部分。

Figure 1-9  Layers associated with a window

 

如圖1-10所示,每個圖層樹上的對象都有一個對應的對象在渲染樹和呈現樹上。和以前提到的同樣,APP開發中主要使用圖層樹中的對象,可是有時能夠須要獲取渲染樹上的對象。尤爲是,經過圖層樹內Layer對象的presentationLayer屬性能夠獲取對應的呈現樹上的對象,咱們能夠經過獲取這個對象讀取當前動畫過程當中某個屬性的值。

                          Figure 1-10  The layer trees for a window

 

重要提醒:咱們應該僅僅在動畫執行過程當中獲取呈現樹上的對象。當一個動畫還在執行過程當中,渲染樹包含Layer在屏幕上那一瞬間顯示的值。這個值是不一樣於模型樹的,模型樹只會反映動畫終點狀態的值。

 

 Layers和Views 之間的關係

 

Layers不是APP中Views的替代品,也就是說咱們不能建立一個僅僅基於Layer對象的可視化界面。Layers爲View提供關鍵基礎。尤爲是,Layers讓它繪製Views的Content和給Views的ContentView更高效以及更方便,而且可以維持高幀率。然而,有許多事情是Layer是沒法作到的,Layers沒法處理事件、繪製content、參與響應者鏈條以及好多其餘事情。出於這些緣由,每一個APP必須有一個或更多Views去處理這些交互。

在iOS中,每一個Views默認被嵌入一個對應的Layer對象,可是在OS X中咱們必須本身指定哪些Views應該內建Layer。在OS X v10.8和以後,給全部Views添加Layer纔有意義,然而咱們咱們不必這麼作,當不是必須及指定layer這種消耗沒有保證的時候咱們仍舊能夠禁止爲Views的Layers添加。Layers確實增長APP的內存,可是Layers帶來的優勢多餘缺點,所以在禁止Layer的支持前最好先測試下APP的性能。

當咱們開啓某個View的Layer支持時,就建立了一個被置爲layer-backed view。在layer-backed view中,系統是有責任建立該View附屬的Layer並同時將建立的Layer與View對應保存。全部的iOS中的Views都是layer-backed ,大部分OS X中的View也是同樣的。然而,OS X中,咱們也建立Layer-hosting view,這種View須要咱們本身建立一個Layer,對於這中View,AppKit具備管理他的方式而且在View改變時候不調整它。

提示:對於layer-backed views而言,不管什麼時候,都推薦操做View而不是操做他的Layer。在iOS中View僅僅是一個Layer對象的簡單包裝,所以操做處理Layer一般更好。可是,有些時候在iOS和OS X中直接操做Layer可能不會產生預期的效果。此核心動畫編程指南將會指出這些陷阱並提供避免他們的方式。

除了和Views關聯的Layers外,咱們也能夠建立一個沒有對應View的Layer對象。咱們將的Layer對象嵌入到其餘Layer對象裏,例如嵌入到和View關聯的Layer裏。咱們尤爲可使用單獨的Layer做爲特殊優化的一部分,例如,若是咱們想要使用一樣的圖片在許多地方,咱們能夠加載這個圖片一次,並使它和許多單獨的Layer對象關聯,並將這些Layer對象添加到圖層樹上,每個Layer因而就引用這個圖片資源而不是嘗試去再次建立該圖片並拷貝到內存中。

 

關於如何開啓Layer的支持,參見Enabling Core Animation Support in Your App。關於如何建立一個Layer對象層次和合適應該建立一個對象層次的建議參見Building a Layer Hierarchy(後續會有譯文)。

 

注:後續我將會有新的翻譯更新,以爲不錯的朋友能夠暫等下

相關文章
相關標籤/搜索