IOS核心動(dòng)畫高級(jí)一:圖層樹

圖層樹

先來介紹幾個(gè)我們常見的名詞:
Core Animation:只看它的名字會(huì)讓人產(chǎn)生一種誤解——核心動(dòng)畫渗勘。從功能方面來看這并不能體現(xiàn)他的強(qiáng)大之處通铲,Core Animation 是從一個(gè)Layer Kit 的庫(kù)演變而來的(當(dāng)然 Layer Kit 這個(gè)名字就不會(huì)讓我們直接聯(lián)想到動(dòng)畫相關(guān)了),動(dòng)畫對(duì) Core Animation 來說只是其中的一部分糕珊。

Core Animation 是一個(gè)復(fù)合引擎尤蒿,它的職責(zé)就是盡可能快的組合屏幕上不同的可視內(nèi)容必逆,這個(gè)內(nèi)容是被分解成獨(dú)立的圖層吗氏,存儲(chǔ)在一個(gè)叫做圖層樹的體系之中芽偏。**于是這個(gè)樹形成了UIKit 和在ios應(yīng)用程序中你所能在屏幕上看見的一切內(nèi)容的基礎(chǔ)。

在開始核心動(dòng)畫之前弦讽,我們先從圖層樹開始污尉,了解一些 Core Animation 的靜態(tài)組合和“布局特性”。

圖層與視圖

視圖——UIView

如果你在ios應(yīng)用程序的開發(fā)經(jīng)驗(yàn)坦袍,對(duì)視圖概念應(yīng)該是比較熟悉十厢,一個(gè)視圖就是一個(gè)屏幕上顯示的矩形塊(比如圖片,視頻捂齐、文字)蛮放,同時(shí)它能夠攔截類似鼠標(biāo)點(diǎn)擊或者觸摸手勢(shì)等的用戶輸入。視圖在層級(jí)關(guān)系中可以互相嵌套奠宜,一個(gè)視圖可以管理它所有子視圖的位置包颁。

1.1——左邊是ios屏幕顯示效果,右邊是形成視圖的層級(jí)關(guān)系.jpeg

在 ios 中所有的視圖都是從 UIView 基類中派生出來的压真,UIView 可以處理觸摸事件娩嚼,可以支持基于 Core Graphics 的繪制,可以做仿射變換(例如旋轉(zhuǎn)或者縮放)滴肿,或者簡(jiǎn)單的類似于滑動(dòng)(frame)或者漸變(alpha)的動(dòng)畫岳悟。

圖層——CALayer

CALayer 和 UIView 在概念上類似,同樣也是一些被層級(jí)關(guān)系樹管理的矩形塊泼差,同樣也包含一些內(nèi)容(比如圖片贵少,文字,背景色)堆缘,同樣它也管理他所有的子圖層的位置滔灶,它們也有一些方法和屬性用來做動(dòng)畫和變換。 和 UIView 最大的不同是:CALayer 不處理用戶的交互(類似鼠標(biāo)點(diǎn)擊吼肥,觸摸手勢(shì))

CALayer 并不清楚具體的響應(yīng)鏈(ios 通過視圖層級(jí)關(guān)系用來傳遞觸摸事件的機(jī)制)录平,所以它并不能夠響應(yīng)事件,即使他提供了一些方法來判斷是否一個(gè)觸點(diǎn)在圖層范圍之內(nèi)(后文有介紹)缀皱。

平行的層級(jí)關(guān)系

每一個(gè) UIView 都有一個(gè) CALayer 類型的圖層屬性斗这。也就是所謂的 backing layer(永久層),視圖的職責(zé)就是創(chuàng)建并管理這個(gè)圖層啤斗,以確保子視圖在層級(jí)關(guān)系中添加或者刪除的時(shí)候表箭,他們關(guān)聯(lián)的圖層也同樣對(duì)應(yīng)在層級(jí)關(guān)系樹中有相同的操作

1.2——左邊是圖層的樹狀結(jié)構(gòu),右邊是對(duì)應(yīng)的視圖層級(jí)

實(shí)際上這些背后關(guān)聯(lián)的圖層才是真正用來在屏幕上顯示和做動(dòng)畫的争占, UIView 僅僅是對(duì)它的一個(gè)封裝燃逻,提供了一些ios類似處理觸摸事件的一些具體功能。以及一些使用 Core Animation 底層方法的高級(jí)接口臂痕。

此時(shí)大家可能就有疑問:IOS為什么要基于 UIView 和 CALayer 提供兩套平行的層級(jí)關(guān)系呢伯襟?為什么不使用一個(gè)簡(jiǎn)單的層級(jí)來處理所有的事情?好問題握童,原因在于 要做職責(zé)分離姆怪,這樣也能避免很多重復(fù)代碼。在 ios 和 macOS 兩個(gè)平臺(tái)上澡绩,事件和用戶交互有很多地方的不同稽揭,基于多點(diǎn)觸控的用戶界面和基于鼠標(biāo)和鍵盤有著本質(zhì)的區(qū)別,這就是為什么ios有 UIKit 和 UIView , MacOS 有AppKit 和 NSView 肥卡。他們?cè)诠δ芎芟嗨葡疲窃趯?shí)現(xiàn)上有著顯著的區(qū)別。

繪圖步鉴、布局和動(dòng)畫相比之下就是類似Mac 筆記本和桌面系列一樣應(yīng)用于iPhone和iPad觸屏的概念揪胃。把兩個(gè)平臺(tái)上的這種功能的邏輯分開應(yīng)用到獨(dú)立的 Core Animation 框架,使得蘋果的OS團(tuán)隊(duì)和第三方開發(fā)者去開發(fā)兩個(gè)平臺(tái)的應(yīng)用更加便捷氛琢。

實(shí)際上喊递,這里并不是兩個(gè)層級(jí)關(guān)系,而是四個(gè)阳似,每一個(gè)都扮演不同的角色骚勘,除了視圖層級(jí)和圖層樹之外,還存在呈現(xiàn)樹渲染樹撮奏,我們?cè)诤竺娴慕榻B俏讹。

圖層CALayer的能力

如果說 CALayer 是 UIView 的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),那 我們?yōu)槭裁催€要費(fèi)勁心思的了解他呢挽荡?當(dāng)然蘋果位我們提供了優(yōu)美簡(jiǎn)潔的 UIView 的接口藐石,那么我們是否就沒有必要直接去處理 Core Animation 一些實(shí)現(xiàn)上的細(xì)節(jié)了呢?

在某種程度是確實(shí)是這樣定拟,對(duì)一些簡(jiǎn)單的需求來說于微,我們確實(shí)沒有必要處理 CALayer , 蘋果已經(jīng)通過UIView 的高級(jí)API間接地使得動(dòng)畫變得很簡(jiǎn)單。

但是這種簡(jiǎn)單不可避免的會(huì)帶來靈活上的一些缺陷青自、如果你略微想在底層做一些改變株依,或是想要使用一些蘋果沒有在 UIView 中實(shí)現(xiàn)的接口功能,這時(shí)候處了介入Core Animation底層之外 別無(wú)其他選擇延窜。

我們已經(jīng)證實(shí)了圖層不能像視圖那樣處理觸摸時(shí)間恋腕,那它能做那些視圖不能做的呢?舉例一些 UIView 沒有暴露出的 CALayer 功能逆瑞。

  • 圓角荠藤,陰影伙单,帶顏色的邊框
  • 3D的動(dòng)畫變換
  • 非舉行范圍繪制然眼。
  • 透明遮罩
  • 多級(jí)非線性動(dòng)畫

跟著我們學(xué)習(xí)的腳步衰絮,我們會(huì)一一為大家講解這些功能,但在此之前见间,我們首先要關(guān)注最基本的淤井,CALayer 是如何被使用的布疼。

使用圖層

我們使用代碼的形式進(jìn)行演示,
創(chuàng)建項(xiàng)目的代碼我們就省去了币狠,節(jié)約大家時(shí)間
項(xiàng)目創(chuàng)建完成

項(xiàng)目創(chuàng)建完成.png

首先我們?cè)趧?chuàng)建一個(gè)子視圖(layerView)添加到 viewController 的視圖上游两。
效果如下:

子視圖效果.png

然而這并沒有什么卵用,
我們想要在白色的視圖中添加一個(gè)藍(lán)色的區(qū)域漩绵,當(dāng)然你可以通過添加子視圖的方式實(shí)現(xiàn)贱案,但這對(duì)我們的學(xué)習(xí)layer沒有什么卵用。

因此我們通過創(chuàng)建圖層來完成渐行。于是呢我們創(chuàng)建一個(gè)layer圖層轰坊,并且把它作為我們視圖相關(guān)圖層的子圖層。盡管 UIView 的接口中暴露了圖層屬性祟印,但是標(biāo)準(zhǔn)的Xcode項(xiàng)目并包含Core Animation 的相關(guān)頭文件肴沫,所以如果我們不給項(xiàng)目添加合適的庫(kù),是不能使用任何圖層相關(guān)的方法或者訪問他的屬性的蕴忆。所以首先需要添加QuartzCore 框架到building phases下颤芬。
如圖所示:

添加庫(kù).png

之后就可以在代碼中應(yīng)用CALayer的屬性和方法了,我們創(chuàng)建一個(gè)Layer 設(shè)置藍(lán)色添加到layerView相關(guān)圖層的子圖層上套鹅,
代碼如下

UIView *layerView = [[UIView alloc] initWithFrame: CGRectMake(100, 100, 200, 200)];
layerView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:layerView];

//添加一個(gè)圖層
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(50, 50, 100, 100);
layer.backgroundColor = [UIColor blueColor].CGColor;
[layerView.layer addSublayer:layer];

咱們看效果:

看效果.png

一個(gè)視圖只有一個(gè)相關(guān)聯(lián)的圖層(自動(dòng)創(chuàng)建)站蝠,同時(shí)它也可以支持添加無(wú)數(shù)多個(gè)子圖層。從上面的例子我們可以看出卓鹿,你可以顯示創(chuàng)建一個(gè)單獨(dú)的圖層菱魔。并且把它直接添加到視圖關(guān)聯(lián)圖層的子圖層。盡管可以這樣添加圖層吟孙,但往往我們只是簡(jiǎn)單地處理視圖澜倦,他們關(guān)聯(lián)的圖層并不需要額外地手動(dòng)添加子視圖。

額外補(bǔ)充:
在 MacOS平臺(tái)杰妓,10.8版本之前藻治,一個(gè)顯著的性能缺陷就是 macOS 使用 UIView視圖層級(jí)而不在一個(gè)單獨(dú)的視圖內(nèi)使用CALayer樹狀層級(jí)。但在IOS平臺(tái)巷挥,使用輕量級(jí)的 UIView類并沒有顯著的性能影響(當(dāng)然在 MacOS 10.8系統(tǒng)之后桩卵,NSView 的性能有了很大的提升)

使用圖層關(guān)聯(lián)視圖層級(jí)而不是用CALayer的好處在于,你能在使用所有CALayer 底層特性的同時(shí),也可以使用UIView提供的高級(jí)API (比如雏节,自動(dòng)排版胜嗓、布局,響應(yīng)事件)

然而在以下場(chǎng)景钩乍,你可能更需要使用CALayer 兼蕊,而不用使用UIView

  • 開發(fā)同時(shí)可以在Mac OS上運(yùn)行的跨平臺(tái)應(yīng)用。
  • 使用多種 CALayer 的子類件蚕,并且不想創(chuàng)建額外的 UIView 去封裝他們。
  • 做一些對(duì)性能特別挑剔的工作产禾,(比如對(duì) UIView 一些可忽略不計(jì)的操作都會(huì)引起性能方面顯著的不同排作,當(dāng)然,你也可以直接使用 openGL繪圖)亚情。
    當(dāng)然這些場(chǎng)景比較少見妄痪,總體來說處理視圖還是比直接處理圖層方便一些。

文章總結(jié):

我們文中闡述了圖層的樹狀結(jié)構(gòu)楞件。說明了如何在ios中由 UIView 的層級(jí)關(guān)系形成的一種平行的CALayer層級(jí)關(guān)系衫生,后面使用Demo進(jìn)行了演示。

未完待續(xù)……

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末土浸,一起剝皮案震驚了整個(gè)濱河市罪针,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黄伊,老刑警劉巖泪酱,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異还最,居然都是意外死亡墓阀,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門拓轻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斯撮,“玉大人,你說我怎么就攤上這事扶叉∥鸸” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵辜梳,是天一觀的道長(zhǎng)粱甫。 經(jīng)常有香客問我,道長(zhǎng)作瞄,這世上最難降的妖魔是什么茶宵? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮宗挥,結(jié)果婚禮上乌庶,老公的妹妹穿的比我還像新娘种蝶。我一直安慰自己,他們只是感情好瞒大,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布螃征。 她就那樣靜靜地躺著,像睡著了一般透敌。 火紅的嫁衣襯著肌膚如雪盯滚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天酗电,我揣著相機(jī)與錄音魄藕,去河邊找鬼。 笑死撵术,一個(gè)胖子當(dāng)著我的面吹牛背率,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嫩与,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼寝姿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了划滋?” 一聲冷哼從身側(cè)響起饵筑,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎处坪,沒想到半個(gè)月后翻翩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡稻薇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年嫂冻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塞椎。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡桨仿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出案狠,到底是詐尸還是另有隱情服傍,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布骂铁,位于F島的核電站吹零,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拉庵。R本人自食惡果不足惜灿椅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茫蛹,春花似錦操刀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至柬采,卻和暖如春欢唾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粉捻。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工匈辱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人杀迹。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像押搪,于是被迫代替她去往敵國(guó)和親树酪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容