圖層樹
- 圖層與視圖
- 圖層的能力
- 使用圖層
- 總結(jié)
Core Animation
是一個(gè)復(fù)合引擎, 他的職責(zé)是盡可能的組合屏幕的不同的可視內(nèi)容, 這個(gè)內(nèi)容是被分解為獨(dú)立的圖層, 存儲(chǔ)在一個(gè)叫做圖層樹的體系之中, 于是這個(gè)樹形成了UIKit以及iOS應(yīng)用程序當(dāng)中你能在屏幕上看到的一切的基礎(chǔ)
在討論動(dòng)畫之前, 我們將從圖層樹開始, 涉及一下core Animation
的靜態(tài)組合以及布局特性
一: 圖層與視圖
一個(gè)視圖就是在屏幕上顯示的一個(gè)矩形塊, 他能夠攔截類似鼠標(biāo)點(diǎn)擊或者觸摸手勢(shì)等輸入行為, 視圖在層級(jí)關(guān)系中可以互相嵌套, 一個(gè)視圖可以管理他的所有子視圖的位置
在iOS中, 所有的視圖都是從一個(gè)叫做UIView的基類派生出來的, UIView可以處理觸摸事件, 可以支持基于core Graphics
繪圖, 可以做仿射變換(旋轉(zhuǎn)或者縮放). 或者簡(jiǎn)單的類似滑動(dòng)或者漸變的動(dòng)畫
1.1: CALayer
CALayer
類在概念上和UIView
相似, 同樣也是一些被層級(jí)關(guān)系樹管理的矩形塊, 同樣也可以包含一些內(nèi)容(圖片买猖、文本、背景色)管理子圖層的位置, 它們有有些方法和屬性用來做動(dòng)畫和變換, 和UIView最大的不同是CALayer不處理用戶的交互.
CALayer
并不清楚具體的響應(yīng)鏈(iOS通過視圖層級(jí)關(guān)系來傳送觸摸事件的機(jī)制), 于是他不能夠響應(yīng)事件, 即使她提供了一些方法來判斷是否一個(gè)觸電是否在圖層范圍內(nèi)
1.2: 平行的層級(jí)關(guān)系
每個(gè)UIView都有一個(gè)CALayer實(shí)例的圖層屬性, 也就是所謂的backing layer
, 視圖的職責(zé)是創(chuàng)建并管理這個(gè)圖層, 以確保子視圖在層級(jí)關(guān)系中添加和移除的時(shí)候, 他們關(guān)聯(lián)頁(yè)同樣對(duì)應(yīng)層級(jí)關(guān)系書當(dāng)中的相同操作
[圖片上傳失敗...(image-e7891f-1512703987307)]
實(shí)際上這些背后關(guān)聯(lián)的圖層礙事真正用來在屏幕上下顯示和做動(dòng)畫的邓尤, UIView僅僅是對(duì)他的封裝, 提供了一些iOS相關(guān)處理觸摸的具體功能, 以及Core Animation
底層方法的高級(jí)接口
但是為什么iOS要基于UIView
和CALayer
提供兩個(gè)平行的層級(jí)關(guān)系那敦跌? 為什么不用一個(gè)簡(jiǎn)單的層級(jí)來處理所有的事情那? 原因在于職責(zé)分離
, 這樣能避免很多重復(fù)代碼
, 在iOS和MacOS兩個(gè)平臺(tái)下, 事情和用戶交互很多地方的不同, 基于多點(diǎn)觸控的用戶界面和基于鼠標(biāo)鍵盤有著本質(zhì)的區(qū)別, 這就是iOS有UIKit和UIView, 但是Mac OS有AppKit和NSView的原因, 他們功能很相似, 但是在實(shí)現(xiàn)上有著顯著的區(qū)別
繪圖慧库、布局和動(dòng)畫, 相比之下就是類似Mac比較本和桌面系列一樣應(yīng)用于iPhone和Ipad觸屏的概念, 吧這種功能的邏輯分開并應(yīng)用到獨(dú)立的Core Animation
框架中, 蘋果就能夠在iOS和Mac OS之間共享代碼, 使得對(duì)蘋果自己的OS開發(fā)團(tuán)隊(duì)和第三方開發(fā)者去方法兩個(gè)平臺(tái)更加便捷
實(shí)際上跷跪, 這里并不是兩個(gè)層級(jí)關(guān)系, 而是四個(gè),每一個(gè)都扮演不同的角色, 除了視圖層級(jí)和圖層樹之外, 還存在呈現(xiàn)樹和渲染樹.
1.3: 圖層的能力
如果說CALayer是UIView的內(nèi)部實(shí)現(xiàn)細(xì)節(jié), 那我們?yōu)槭裁匆娴牧私馑麉龋?蘋果當(dāng)然為我們提供了優(yōu)美簡(jiǎn)潔的UIView接口, 那么我們是否就沒有必要直接處理Core Animation
某種意義上說的的確實(shí)這樣的, 對(duì)一些簡(jiǎn)單的需求來說, 我們沒有必要處理CALayer, 因?yàn)樘O果已經(jīng)通過UIView
的高級(jí)API間接的使得動(dòng)畫變得很簡(jiǎn)單
我們已經(jīng)證實(shí)圖層不能像視圖那樣帶來一些靈活上的缺陷, UIView缺少CALayer的功能
- 陰影 圓角 帶顏色的邊框
- 3D變換
- 非矩形范圍
- 透明遮罩
- 多級(jí)非線性動(dòng)畫
1.4:使用圖層
首先我們來創(chuàng)建一個(gè)簡(jiǎn)單的圖層, 從屏幕中央創(chuàng)建一個(gè)小視圖(200*200),
我們來創(chuàng)建一個(gè)CALayer
, 并且把它作為我們視圖相關(guān)圖層的子圖層, 我們創(chuàng)建一個(gè)CALayer
, 設(shè)置他的backgroundColor
屬性齐板, 然后添加到相應(yīng)的Layer上吵瞻。
[圖片上傳失敗...(image-60588-1512703987307)]
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong)UIView *whiteView;
@property (nonatomic, strong)CALayer *blueLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
[self.view addSubview:self.whiteView];
[self.whiteView.layer addSublayer:self.blueLayer];
}
- (UIView *)whiteView{
if (_whiteView == nil) {
_whiteView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
_whiteView.backgroundColor = [UIColor whiteColor];
_whiteView.center = self.view.center;
}
return _whiteView;
}
- (CALayer *)blueLayer{
if (_blueLayer == nil) {
_blueLayer = [CALayer layer];
_blueLayer.frame = CGRectMake(50, 50, 100, 100);
_blueLayer.backgroundColor = [UIColor blueColor].CGColor;
}
return _blueLayer;
}
@end
使用圖層關(guān)聯(lián)的視圖而不是CALayer
的好處在于, 你可以使用CALayer
底層的特性的同時(shí), 也可以使用UIView
的高級(jí)API(自動(dòng)排版甘磨、布局和事件處理)
如果滿足一下的條件, 你可能需要使用CALayer
而不是UIView
- 開發(fā)同時(shí)可以在
Mac OS
上允許的跨平臺(tái)應(yīng)用 - 使用多種
CALayer
的子類, 并且不想創(chuàng)建額外的UIView
去包裝他們所有 - 做一些對(duì)性能特別挑剔的工作, 比如對(duì)
UIView
一些可以忽略不計(jì)的操作都會(huì)引起顯著的不同
處理視圖比處理Layer要方便一些