Core Animation-1:圖層樹,coreanimation-1

來源:互聯網
上載者:User

Core Animation-1:圖層樹,coreanimation-1
圖層的樹狀結構

>巨妖有圖層,洋蔥也有圖層,你懂嗎?我們都有圖層 -- 史萊克

Core Animation其實是一個令人誤解的命名。你可能認為它只是用來做動畫的,但實際上它是從一個叫做*Layer Kit*這麼一個不怎麼和動畫有關的名字演變而來,所以做動畫這隻是Core Animation特性的冰山一角。

Core Animation是一個*複合引擎*,它的職責就是儘可能快地組合螢幕上不同的可視內容,這個內容是被分解成獨立的*圖層*,儲存在一個叫做*圖層樹*的體系之中。於是這個樹形成了**UIKit**以及在iOS應用程式當中你所能在螢幕上看見的一切的基礎。

在我們討論動畫之前,我們將從圖層樹開始,涉及一下Core Animation的*靜態*組合以及布局特性。

##圖層和視圖
如果你曾經在iOS或者Mac OS平台上寫過應用程式,你可能會對*視圖*的概念比較熟悉。一個視圖就是在螢幕上顯示的一個矩形塊(比片,文字或者視頻),它能夠攔截類似於滑鼠點擊或者觸摸手勢等使用者輸入。視圖在層級關係中可以互相嵌套,一個視圖可以管理它的所有子視圖的位置。圖1.1顯示了一種典型的視圖層級關係

 

圖1.1 一種典型的iOS螢幕(左邊)和形成視圖的層級關係(右邊)

在iOS當中,所有的視圖都從一個叫做`UIVIew`的基類派生而來,`UIView`可以處理觸摸事件,可以支援基於*Core Graphics*繪圖,可以做仿射變換(例如旋轉或者縮放),或者簡單的類似於滑動或者漸層的動畫。

###CALayer
`CALayer`類在概念上和`UIView`類似,同樣也是一些被層級關係樹管理的矩形塊,同樣也可以包含一些內容(像圖片,文本或者背景色),管理子圖層的位置。它們有一些方法和屬性用來做動畫和變換。和`UIView`最大的不同是`CALayer`不處理使用者的互動。

`CALayer`並不清楚具體的*響應鏈*(iOS通過視圖層級關係用來傳送觸摸事件的機制),於是它並不能夠響應事件,即使它提供了一些方法來判斷是否一個觸點在圖層的範圍之內(具體見第三章,“圖層的幾何學”)

###平行的層級關係
每一個`UIview`都有一個`CALayer`執行個體的圖層屬性,也就是所謂的*backing layer*,視圖的職責就是建立並管理這個圖層,以確保當子視圖在層級關係中添加或者被移除的時候,他們關聯的圖層也同樣對應在層級關係樹當中有相同的操作(見圖1.2)。

 

圖1.2 圖層的樹狀結構(左邊)以及對應的視圖層級(右邊)

實際上這些背後關聯的圖層才是真正用來在螢幕上顯示和做動畫,`UIView`僅僅是對它的一個封裝,提供了一些iOS類似於處理觸摸的具體功能,以及Core Animation底層方法的進階介面。

但是為什麼iOS要基於`UIView`和`CALayer`提供兩個平行的層級關係呢?為什麼不用一個簡單的層級來處理所有事情呢?原因在於要做職責分離,這樣也能避免很多重複代碼。在iOS和Mac OS兩個平台上,事件和使用者互動有很多地方的不同,基於多點觸控的使用者介面和基於滑鼠鍵盤有著本質的區別,這就是為什麼iOS有UIKit和`UIView`,但是Mac OS有AppKit和`NSView`的原因。他們功能上很相似,但是在實現上有著顯著的區別。

繪圖,布局和動畫,相比之下就是類似Mac筆記本和案頭系列一樣應用於iPhone和iPad觸屏的概念。把這種功能的邏輯分開並應用到獨立的Core Animation架構,蘋果就能夠在iOS和Mac OS之間共用代碼,使得對蘋果自己的OSTeam Dev和第三方開發人員去開發兩個平台的應用更加便捷。

實際上,這裡並不是兩個層級關係,而是四個,每一個都扮演不同的角色,除了視圖層級和圖層樹之外,還存在*呈現樹*和*渲染樹*,將在第七章“隱式動畫”和第十二章“效能調優”分別討論。

###圖層的能力
如果說`CALayer`是`UIView`內部實現細節,那我們為什麼要全面地瞭解它呢?蘋果當然為我們提供了優美簡潔的`UIView`介面,那麼我們是否就沒必要直接去處理Core Animation的細節了呢?

某種意義上說的確是這樣,對一些簡單的需求來說,我們確實沒必要處理`CALayer`,因為蘋果已經通過`UIView`的進階API間接地使得動畫變得很簡單。

但是這種簡單會不可避免地帶來一些靈活上的缺陷。如果你略微想在底層做一些改變,或者使用一些蘋果沒有在`UIView`上實現的介面功能,這時除了介入Core Animation底層之外別無選擇。

我們已經證實了圖層不能像視圖那樣處理觸摸事件,那麼他能做哪些視圖不能做的呢?這裡有一些`UIView`沒有暴露出來的CALayer的功能:

* 陰影,圓角,帶顏色的邊框
* 3D變換
* 非矩形範圍
* 透明遮罩
* 多級非線性動畫

我們將會在後續章節中探索這些功能,首先我們要關注一下在應用程式當中`CALayer`是怎樣被利用起來的。

##使用圖層
首先我們來建立一個簡單的項目,來操縱一些`layer`的屬性。開啟Xcode,使用*Single View Application*模板建立一個工程。

在螢幕中央建立一個小視圖(大約200 X 200的尺寸),當然你可以手工編碼,或者使用Interface Builder(隨你方便)。確保你的視圖控制器要添加一個視圖的屬性以便可以直接存取它。我們把它稱作`layerView`。

運行項目,應該能在淺灰色螢幕背景中看見一個白色方塊(圖1.3),如果沒看見,可能需要調整一下背景window或者view的顏色

 

圖1.3 灰色背景上的一個白色`UIView`

這並沒有什麼令人激動的地方,我們來添加一個色塊,在白色方塊中間添加一個小的藍色塊。

我們當然可以簡單地在已經存在的`UIView`上添加一個子視圖(隨意用代碼或者IB),但這不能真正學到任何關於圖層的東西。

於是我們來建立一個`CALayer`,並且把它作為我們視圖相關圖層的子圖層。儘管`UIView`類的介面中暴露了圖層屬性,但是標準的Xcode項目模板並沒有包含Core Animation相關標頭檔。所以如果我們不給項目添加合適的庫,是不能夠使用任何圖層相關的方法或者訪問它的屬性。所以首先需要添加QuartzCore架構到Build Phases標籤(圖1.4),然後在vc的.m檔案中引入<QuartzCore/QuartzCore.h>庫。

<img src="./1.4.jpeg" alt="圖1.4" title="圖1.4" width="700"/>

圖1.4 把QuartzCore庫添加到項目

之後就可以在代碼中直接引用`CALayer`的屬性和方法。在清單1.1中,我們用建立了一個`CALayer`,設定了它的`backgroundColor`屬性,然後添加到`layerView`背後相關圖層的子圖層(這段代碼的前提是通過IB建立了`layerView`並做好了串連),圖1.5顯示了結果。

清單1.1 給視圖添加一個藍色子圖層
``` objective-c
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView;

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
//create sublayer
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
//add it to our view
[self.layerView.layer addSublayer:blueLayer];
}
@end
```

 

圖1.5 白色`UIView`內部嵌套的藍色`CALayer`

一個視圖只有一個相關聯的圖層(自動建立),同時它也可以支援添加無數多個子圖層,從清單1.1可以看出,你可以顯示建立一個單獨的圖層,並且把它直接添加到視圖關聯圖層的子圖層。儘管可以這樣添加圖層,但往往我們只是見簡單地處理視圖,他們關聯的圖層並不需要額外地手動添加子圖層。

在Mac OS平台,10.8版本之前,一個顯著的效能缺陷就是由於用了視圖層級而不是單獨在一個視圖內使用`CALayer`樹狀層級。但是在iOS平台,使用輕量級的`UIView`類並沒有顯著的效能影響(當然在Mac OS 10.8之後,`NSView`的效能同樣也得到很大程度的提高)。

使用圖層關聯的視圖而不是`CALayer`的好處在於,你能在使用所有`CALayer`底層特性的同時,也可以使用`UIView`的進階API(比如自動排版,布局和事件處理)。

然而,當滿足以下條件的時候,你可能更需要使用`CALayer`而不是`UIView`

* 開發同時可以在Mac OS上啟動並執行跨平台應用
* 使用多種`CALayer`的子類(見第六章,“特殊的圖層“),並且不想建立額外的`UIView`去包封裝它們所有
* 做一些對效能特別挑剔的工作,比如對`UIView`一些可忽略不計的操作都會引起顯著的不同(儘管在這種情況下,你可能會想直接使用OpenGL來繪圖)


但是這些例子都很少見,總的來說,處理視圖會比單獨處理圖層更加方便。

##總結
這一章闡述了圖層的樹狀結構,說明了如何在iOS中由`UIView`的層級關係形成的一種平行的`CALayer`層級關係,在後面的實驗中,我們建立了自己的`CALayer`,並把它添加到圖層樹中。

在第二章,“圖層關聯的圖片”,我們將要研究一下`CALayer`關聯的圖片,以及Core Animation提供的操作顯示的一些特性。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.