關於Core Animation動畫(上)

關於Core Animation動畫(上)

1. UIView與CALayer

對於UIViewCALayer,你們應該都很熟悉。一般咱們瞭解到UIView是經過視圖樹的結構來組織起來的,實際上,UIView管理並維護了另外一個圖層樹(即CALayer樹),真正的在屏幕上顯示與動畫的其實是CALayer對象。oop

若是說CALayer是View的內部實現細節,那麼爲何蘋果要再封裝一層UIView呢,UIView與CALayer的區別又是什麼呢?
UIView與CALayer最大的區別就是UIView能夠處理用戶的交互(如點擊事件),而CALayer是不清楚具體的響應者鏈的,其不可以響應事件。
將響應事件抽象到UIView中的緣由,是爲了與Mac OS公用一套底層代碼(即layer層)。在Mac OS中有一個NSView的類,會用來處理一些與iOS不一樣的用戶事件(好比鍵盤鼠標)。動畫

對於大部分的簡單場景,UIView均可以知足咱們的要求。那麼研究CALayer有什麼用呢?
前面咱們瞭解CALayer是沒法像UIView那樣處理觸摸事件的,UIView也有一些沒有暴露出來的CALayer的功能:code

  • 陰影,圓角,邊框對象

  • 3D變換(UIView只有2D變換)事件

  • 透明遮罩事務

  • 非矩形範圍animation

  • 非線性動畫博客

  • 其餘不少功能,it

實際上,每一個UIView都有一個CALayer實例的圖層屬性,咱們能夠經過view.layer來獲取。
CALayer有不少特殊的子類,能夠實現不少不一樣的效果,大概能夠看看CALayer具體有哪些子類。咱們既能夠改變UIView的CALayer類別,也能夠爲其添加不一樣的CALayer實例。這裏暫時不講太多,本章主要仍是以動畫爲主。io

2. 隱式動畫

瞭解CALayer與UIView,咱們能夠來看看隱式動畫,瞭解什麼狀況下,系統會自動產生動畫。什麼狀況下,須要咱們本身添加動畫。

隱式動畫其實是由事物來產生的,咱們先看看事物的概念:

2.1 事務

事務其實是Core Animation用來包含一系列屬性動畫集合的機制,任何對CALayer的屬性改變都不會馬上發生變化,而是在事務提交後,用一個動畫過分到新值。

Core Animation在每一個run loop週期中自動開始一次新的事務,任何在一次run loop循環中屬性的改變都會集中起來,而後作一次0.25秒的動畫。

好比說,咱們添加一個新的layer到視圖上,改變其backGroundColor,會發現顏色不是瞬間就改變的,而是通過了0.25s(動畫的默認時長)的時間漸變過來。

//CALayer的隱式動畫
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //建立一個紅色的layer
    _layer = [CALayer layer];
    _layer.frame = self.view.bounds;
    _layer.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:_layer];
}

- (IBAction)changeColor:(id)sender {
    //修改layer的顏色爲黃色   此時,顏色是由紅色漸變到黃色的
    _layer.backgroundColor = [UIColor yellowColor].CGColor;
}
上面就是隱式動畫產生的緣由,每一個run loop中的會默認開啓一個事務來完成CALayer的隱私動畫。 須要注意的是,UIView所關聯的layer,是禁用了隱式動畫的。這個時候咱們須要本身來實現動畫:

咱們能夠經過CATransaction的+begin和+commit來入棧或者出棧一個新的事務(也可使用UIView的一些快捷方法,如+beginAnimations:context:和+animateWithDuration:animations:,他們本質上是同樣的),在新建的事務中,咱們能夠修改一些動畫相關的設定,好比說duration動畫時間,而這些設定是隻對當前事務有效的,不會影響到默認run loop中的事務。

//對View作動畫,須要包含在事物中
[CATransaction begin];
self.view.backgroundColor = [UIColor yellowColor];     //改變view顏色
[CATransaction setAnimationDuration:1];             //修改本次事務的動畫時間
[CATransaction setCompletionBlock:^{                   //動畫結束後回調
    NSLog(@"animation completed");
}];
[CATransaction commit];  //提交動畫

2.2 modelLayer與presentationLayer

從上面的部分咱們知道了CALayer的屬性發生變化,會經過一段動畫時間來漸變動新,而咱們只是設置了backColor的起始值和結束值(由紅色變爲黃色)。那麼是否有辦法獲取到動畫中間狀態的backColor呢?

答案是能夠的,咱們須要瞭解2個概念,modelLayerpresentationLayer

多數狀況下,咱們建立的一個CALayer實例,是指的modelLayer(能夠稱爲數據圖層)。咱們對一個layer對象調用-modelLayer一般會返回-self。當一個layer的屬性發生變化時,modelLayer的屬性值馬上(動畫開始前)就發生了變化,在上面的例子中,modelLayer的值是馬上從紅色變爲黃色的。

而presentationLayer稱爲展示圖層,它其實是modelLayer的一份拷貝,表示了任意時刻屏幕顯示的layer的真實值。也即動畫過程當中layer中間態的屬性值,能夠經過presentationLayer來獲取。
須要注意的是隻有layer在第一次屏幕上顯示時,presentationLayer纔會被建立,在這以前-presentationLayer返回的是nil。

總結一下

  1. 咱們瞭解了CAlayer是UIView的底層實現,UIView能夠處理一些用戶觸摸的事件,而CALayer則提供了更豐富的底層功能。

  2. 對於CALayer的屬性改變,runloop會有一個默認的事物來進行隱式動畫,而UIView則禁用掉了隱私動畫,咱們能夠經過提交一個新的事物來對UIView的屬性改變賦予一個能夠控制的動畫效果。

  3. 咱們瞭解了modelLayer的屬性是在修改後馬上就變爲終值的,而presentationLayer則會經歷一個漸變的修改過程,這對於一些交互性的動畫頗有幫助。

後續可能會講一些Core Animation其餘的東西,好比說顯示動畫,渲染樹之類

轉載請註明出處,個人博客: luoyibu

相關文章
相關標籤/搜索