核心動畫學習筆記

1、核心動畫框架



  • CAScrollLayer  CALayer 的子類,簡化顯示圖層的一部分內容。CAScrollLayer 對象的滾動區域的範圍在它的子圖層裏面定義。CAScrollLayer 不提供鍵盤或鼠標事件處理,也不提供可見的滾動條。
  • CATextLayer 可以方便的從字符串或字符串的內容創建一個圖層類的內容。 
  • CATiledLayer 允許遞增的顯示大而複雜的圖片。
  • CAEAGLLayer 提供了一個OpenGLES渲染環境。
  • CATransition 提供了一個圖層變化的過渡效果,它能影響圖層的整個內容。 動畫進行的時候淡入淡出(fade)、推(push)、顯露(reveal)圖層的內容。這些過渡效 果可以擴展到你自己定製的 Core Image 濾鏡(CIFilter,ios暫不可用)。
  • CAAnimationGroup 允許一系列動畫效果組合在一起,並行顯示動畫。
  • CAPropertyAnimation 是一個抽象的子類,它支持在動畫的顯示圖層的關鍵路徑中指定的屬性
  • CABasicAnimation 簡單的對圖層的屬性提供修改。
  • CAKeyframeAnimation 支持關鍵幀動畫,你可以指定圖層屬性的關鍵路徑動畫,包括動畫在每個階段的值,以及關鍵幀時間和計時功能的一系列值。在 動畫運行時,每個值被特定的插入值替代



CAConstraint  類是一個佈局管理器,用於描述層的幾何屬性(左,右,頂部或底部的邊緣或水平或垂直中心)的關係。

CATransaction 在覈心動畫裏面負責協調多個動畫原子更新顯示操作,圖層的動畫屬性的每一個修改必然是事務的一部分。

隱式事務和顯式事務
在圖層的動畫屬性被一個線程修改,同時該線程下次迭代的時候自動提交該修改的時候隱式事務自動創建。顯式事務 發生在程序在修改動畫屬性之前給 CATransaction 發送了一個開始消息,在動畫屬性

修改之後提交該消息。

2、圖層, layer

圖層的 anchorPoint 屬性是一個 CGPoint 值,它指定了一個基於圖層 bounds 的符 合位置座標系的位置。錨點(anchor point)指定了 bounds 相對於 position(相當於view的center) 的值,同時也作爲變換時候的支點。錨點使用單元空間座標系表示,(0.0,0.0)點接近圖層 的原點,而(1.0,1.0)是原點的對角點




3、變換矩陣
CATransform3D 變換矩陣 4*4
CGAffineTransform 仿射矩陣 [ a b c d tx ty ]

核心動畫擴展了鍵-值編碼協議,允許通過關鍵路徑獲取和設置一個圖層的 CATransform3D 矩陣的值。表 4 描述了圖層的 transform 和 sublayerTransform 屬性的 相應關鍵路徑。

Table 4 CATransform3D key paths

你不可以通過Objective-C 2.0的屬性方法來指定一個結構字段的關鍵路徑如下的代碼是無法正常執行的::
 myLayer.transform.rotation.x=0;

替換的辦法是,你必須通過 setValue:forKeyPath:或者 valueForKeyPath:方法, 具體如下:

 [myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];

4、每個UIView會自動創建一個CALayer類的實例,然後賦值給layer屬性



maskToBounds屬性決定子圖層是否相對於父圖層裁剪


5、給CALayer 提供內容



通過delegat: // 一般是layer所在的view
displayLayer: 或 drawLayer:inContext:

觸發上面的回調
setNeedsDisplay、setNeedsDisplayInRect:、或者把圖層的needsDisplayOnBoundsChange屬性設置爲YES。


- (void)drawLayer:(CALayer *)theLayer inContext:(CGContextRef)theContext
{
     CGMutablePathRef thePath = CGPathCreateMutable();
     
     CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
     
     CGPathAddCurveToPoint(thePath,
                           NULL,
                           15.f,250.0f,
                           295.0f,250.0f,
                           295.0f,15.0f);
     
     
     CGContextBeginPath(theContext);
     CGContextAddPath(theContext, thePath);
     CGContextSetLineWidth(theContext,
                           
                           [[theLayer valueForKey:@"lineWidth"] floatValue]);
     CGContextStrokePath(theContext);
     
     // release the path
     CFRelease(thePath);
}

6、修改圖層內容位置
layer的contentsGravity屬性








7、圖層Action
當一個行爲觸發器發生的時候,圖層的actionForKey:方法被調用。此方法返回一個行爲對象(滿足CAAction協議的對象),對應的標識符作爲參數,或如果行爲對象不存在的話返回nil。

    當CALayer爲一個標識符實現的actionForKey:方法被調用的時候,以下的搜索模式將會被用到:

  1. 如果一個圖層有委託,那方法actionForLayer:forKey:的實現將會被調用,把圖層和行爲標識符作爲參數。委託的actionForLayer:forKey:的實現需要響應如下:
    • 返回一個行爲標識符對應的行爲對象。
    • 返回nil,當無法處理行爲標識符的時候。
    • 返回NSNull,當無法處理行爲標識符,而且搜索需要被終止的時候。
  2. 圖層的actions字典被搜索以便找到一個和行爲標識符對應的對象。
  3. 圖層的style屬性被搜索以便找到一個包含行爲標識符的actions字典。
  4. 圖層類發生一個defaultActionForKey:的消息。它將會返回一個和標識符對應的行爲對象,如果不存在的話則返回nil。

通常行爲對象是CAAnimation的子類實例,它實現了CAAction協議。然而你也可以返回任何實現了CAAction協議的類對象。當實例收到runActionForKey:object:arguments:的消息時,它需要執行相應的行爲。

代碼 1  runActionForKey:object:arguments: 的實現:啓動動畫

- (void)runActionForKey:(NSString *)key
                 object:(id)anObject
              arguments:(NSDictionary *)dict
{
     [(CALayer *)anObject addAnimation:self forKey:key];
}

重載隱式動畫

通過插入一個CAAnimation的實例到style字典裏面的actions的字典裏面,通過實現委託方法actionForLayer:forKey:或者繼承圖層類並重載defaultActionForKey:方法返回一個相應的行爲對象。
代碼2的示例通過委託替換contents屬性的隱式動畫。
- (id<CAAction>)actionForLayer:(CALayer *)theLayer
                        forKey:(NSString *)theKey
{
    CATransition *theAnimation=nil;

    if ([theKey isEqualToString:@"contents"])
    {

        theAnimation = [[CATransition alloc] init];
        theAnimation.duration = 1.0;
        theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
        theAnimation.type = kCATransitionPush;
        theAnimation.subtype = kCATransitionFromRight;
    }

    return theAnimation;
}

代碼3的示例使用actions字典模式禁用sublayers屬性的默認動畫。
// get a mutable version of the current actions dictionary
NSMutableDictionary *customActions=[NSMutableDictionary dictionaryWithDictionary:[theLayer actions]];

// add the new action for sublayers
[customActions setObject:[NSNull null] forKey:@"sublayers"];

// set theLayer actions to the updated dictionary 
theLayer.actions=customActions;

8、事務

 隱式事務

當圖層樹被沒有獲得事務的線程修改的時候將會自動創建隱式事務,當線程的運行循環(run-loop)執行下次迭代的時候將會自動提交事務。
重要:當在一個沒有運行循環(runloop)的線程修改圖層的屬性的時候,你必須使用顯式的事務,所以UI處理都必須放主線程。子線程默認都沒有runloop的

顯式事務


臨時禁用圖層的action


你可以在修改圖層屬性值的時候通過設置事務的kCATransactionDisableActions值爲YES來暫時禁用圖層的行爲。在事務範圍所作的任何更改也不會因此而發生的動畫。

代碼2顯示了一個示例,當把aLayer從可視化圖層樹移除的時候禁用淡出動畫。
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];

你可以暫時改變響應改變圖層屬性的動畫的時間,通過設置事務的kCATransactionAnimationDuration鍵的值爲新的時間

代碼4 中顯示了一個嵌套兩個事務的例子。最外層的事務設置隱式動畫的時間爲2秒,並設置圖層的position屬性值。內層的事務設置隱式動畫的時間爲5秒,並修改圖層的opacity和zPosition屬性值。
[CATransaction begin]; // outer transaction
 
// change the animation duration to 2 seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
                forKey:kCATransactionAnimationDuration];
// move the layer to a new position
theLayer.position = CGPointMake(0.0,0.0);
 
[CATransaction begin]; // inner transaction
// change the animation duration to 5 seconds
[CATransaction setValue:[NSNumber numberWithFloat:5.0f]
                 forKey:kCATransactionAnimationDuration];
 
// change the zPosition and opacity
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
 
[CATransaction commit]; // inner transaction
[CATransaction commit]; // outer transaction


9、鍵-值編碼兼容的容器類

CALayer和CAAnimation都是鍵-值編碼兼容的容器類,允許你修改屬性鍵對應的值

爲了給鍵提供默認值,你創建相應的子類,並重載defaultValueForKey:。子類實現相應的鍵參數檢查並返回適當的默認值。清單1描述了一個實現defaultValueForKey:的例子,它給masksToBounds提供新的默認值。

+ (id)defaultValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"masksToBounds"])
         return [NSNumber numberWithBool:YES];
 
    return [super defaultValueForKey:key]; 
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章