iOS隱式動畫機制

weixin_34146805發表於2017-02-27

Core Animation通常對 CALayer 的所有屬性(可動畫的屬性)做動畫,在改變layer層一些屬性的時候,雖然我們都沒有對其進行動畫,但實際上屬性的改變是漸變的,而不是立馬生效。這種自定應用動畫稱作行為。屬性修改應用行為的步驟如下

    1. 圖層首先檢測它是否有委託,並且是否實現CALayerDelegate協議指定的actionForLayer:forKey方法,如果有,直接呼叫並返回結果。
  • 2.如果沒有委託,或者委託沒有實現-actionForLayer:forKey方法,圖層接著檢查包含屬性名稱對於行為對映的actions字典。
  • 3.如果actions字典沒有包含對應的屬性,那麼圖層接著在它的style字典接著搜尋屬性名。
  • 4.最後,如果在style裡面也找不到對應的行為,那麼圖層將會直接呼叫定義了每個屬性標準行為的-defaultActionForKey方法。

經過這一番搜尋會返回一個遵守CAAction協議的物件,該action將會對圖層進行相應的動畫。如果想改變圖層的動畫行為,我們可以在2、3中進行更改,我們知道對layer做顏色改變的時候是一個預設的淡入談出動畫,現在想把它換了,我們只需要進行如下操作

    self.colorLayer = [CALayer layer];
    self.colorLayer.frame = CGRectMake(50.f, 100.f, 50.f, 50.f);
    self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
    //add a custom action
    CATransition *transiton = [CATransition animation];
    transiton.type = kCATransitionPush;
    transiton.subtype = kCATransitionFromLeft;
    self.colorLayer.actions = @{@"backgroundColor":transiton};
    //add it to our view
    [self.view.layer addSublayer:self.colorLayer];

當背景顏色改變的時候,動畫將變為推進過度的效果,建議動手實踐一下

現在來看UIKit是如何禁用隱式動畫的,每個UIView對它的關聯圖層都扮演了一個委託,並且提供了-actionForlayer:forKey的實現方法,當不存在一個動畫塊的實現中,UIView對所有圖層行為返回nil,但是在block範圍之內,它就返回一個非空值。
驗證如下

    NSLog(@"%@", [self.view actionForLayer:self.view.layer forKey:@"backgroundColor"]);
    [UIView beginAnimations:nil context:nil];
    NSLog(@"%@", [self.view actionForLayer:self.view.layer forKey:@"backgroundColor"]);
    [UIView commitAnimations];

控制檯分別列印nil,和一個CABasicAnimation的物件。
當屬性在動畫塊之外發生改變, UIView 直接通過返
回 nil 來禁用隱式動畫。但如果在動畫塊範圍之內,根據動畫具體型別返回相應 的屬性
還有一種禁止隱式動畫的方式

    [CATransaction begin];
    [CATransaction setDisableActions:YES];

對應的UIKit層上的方法

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationsEnabled:NO];

加上這個後,不管是否在快內返回的都是nil。
到這裡我們現在知道該如何對UIKit進行動畫了

  • 關聯的圖層禁用了隱式動畫,對這種圖層做動畫的唯一辦法就是使 用 的動畫函式(而不是依賴 ),或者繼
    承 ,並覆蓋方法,或者直接建立一個顯式動畫
  • 對於單獨存在的圖層,我們可以通過實現圖層的 - actionForLayer:forKey: 委託方法,或者提供一個 actions 字典來控制隱式動畫。

呈現與模型

每個圖層屬性的顯示值都被儲存在一個叫做呈現圖層的獨立圖層當中,他可以通 過 -presentationLayer 方法來訪問。這個呈現圖層實際上是模型圖層的複製, 但是它的屬性值代表了在任何指定時刻當前外觀效果
呈現樹就是通過圖層樹中所有圖層的呈現層所形成。
CAlayer的-modelaye,在呈現圖層上呼叫 -modelaye將會返回它正在呈現所依賴的 CALayer 。通常在一個圖層上呼叫 --modelaye會返回 self。

相關文章