iOS CAAnimation動畫

CAAnimation

CAAnimation 是一個抽像類。CAAnimation 也派生出了很多子類,我們使用動畫,其實也是使用他得子類。

CAAnimation 是所有動畫的父類。

子類三個:


  • CAAnimationGroup //動畫組
  • CAPropertyAnimation //屬性動畫 兩個子類
    • CABasicAnimation 基本動畫
    • CAKeyframeAnimation 關鍵幀動畫
  • CATransition //轉場動畫

一:基本概念

什么是Animation(動畫),簡單點說就是在一段時間內,顯示的內容發生了變化.對CALayer來說就是在一段時間內,其Animatable Property發生了變化.從CALayer(CA = Core Animation)類名來看就可以看出ios的Layer就是為動畫而生的,便于實現良好的交互體驗. 這里涉及到兩個東西: 一是Layer(基類CALayer),一是Animation(基于CAAnimation). Animation作用于Layer.CALayer提供了接口用于給自己添加Animation. 用于顯示的Layer本質上講是一個Model,包含了Layer的各種屬性值. Animation則包含了動畫的時間,變化,以及變化的速度.下面分別詳細講解Layer和Animation相關知識.

二:CALayer及時間模型

我們都知道UIView是MVC中的View.UIView的職責在于界面的顯示和界面事件的處理.每一個View的背后都有一個layer(可以通過view.layer進行訪問),layer是用于界面顯示的.CALayer屬于QuartzCore框架,非常重要,但并沒有想象中的那么好理解.我們通常操作的用于顯示的Layer在Core Animation這層的概念中其實擔當的是數據模型Model的角色,它并不直接做渲染的工作.關于Layer,之前從座標系的角度分析過,這次則側重于它的時間系統.

  • Layer的渲染架構
    Layer也和View一樣存在著一個層級樹狀結構,稱之為圖層樹(Layer Tree),直接創建的或者通過UIView獲得的(view.layer)用于顯示的圖層樹,稱之為模型樹(Model Tree),模型樹的背后還存在兩份圖層樹的拷貝,一個是呈現樹(Presentation Tree),一個是渲染樹(Render Tree). 呈現樹可以通過普通layer(其實就是模型樹)的layer.presentationLayer獲得,而模型樹則可以通過modelLayer屬性獲得(詳情文檔).模型樹的屬性在其被修改的時候就變成了新的值,這個是可以用代碼直接操控的部分;呈現樹的屬性值和動畫運行過程中界面上看到的是一致的.而渲染樹是私有的,你無法訪問到,渲染樹是對呈現樹的數據進行渲染,為了不阻塞主線程,渲染的過程是在單獨的進程或線程中進行的,所以你會發現Animation的動畫并不會阻塞主線程.
  • 事務管理
    CALayer的那些可用于動畫的(Animatable)屬性,稱之為Animatable Properties,這里有一份詳情的列表,羅列了所有的 CALayer Animatable Properties. 如果一個Layer對象存在對應著的View,則稱這個Layer是一個Root Layer,非Root Layer一般都是通過CALayer或其子類直接創建的.下面的subLayer就是一個典型的非Root Layer,它沒有對應的View對象關聯著.
subLayer = [[CALayer alloc] init]; subLayer.frame = CGRectMake(0, 0, 300, 300); subLayer.backgroundColor = [[UIColor redColor] CGColor]; [self.view.layer addSublayer:subLayer];

所有的非Root Layer在設置Animatable Properties的時候都存在著隱式動畫,默認的duration是0.25秒.
subLayer.position = CGPointMake(300,400);
像上面這段代碼當下一個RunLoop開始的時候并不是直接將subLayer的position變成(300,400)的,而是有個移動的動畫進行過渡完成的.
任何Layer的animatable屬性的設置都應該屬于某個CA事務(CATransaction),事務的作用是為了保證多個animatable屬性的變化同時進行,不管是同一個layer還是不同的layer之間的.CATransaction也分兩類,顯式的和隱式的,當在某次RunLoop中設置一個animatable屬性的時候,如果發現當前沒有事務,則會自動創建一個CA事務,在線程的下個RunLoop開始時自動commit這個事務,如果在沒有RunLoop的地方設置layer的animatable屬性,則必須使用顯式的事務.
顯式事務的使用如下:
[CATransaction begin];... [CATransaction commit];
事務可以嵌套.當事務嵌套時候,只有當最外層的事務commit了之后,整個動畫才開始.
可以通過CATransaction來設置一個事務級別的動畫屬性,覆蓋隱式動畫的相關屬性,比如覆蓋隱式動畫的duration,timingFunction.如果是顯式動畫沒有設置duration或者timingFunction,那么CA事務設置的這些參數也會對這個顯式動畫起作用.
還可以設置completionBlock,當當前CATransaction的所有動畫執行結束后, completionBlock會被調用.

  • 時間系統
    CALayer實現了CAMediaTiming協議. CALayer通過CAMediaTiming協議實現了一個有層級關系的時間系統.除了CALayer,CAAnimation也采納了此協議,用來實現動畫的時間系統. 在CA中,有一個Absolute Time(絕對時間)的概念,可以通過CACurrentMediaTime()獲得,其實這個絕對時間就是將mach_absolute_time()轉換成秒后的值.這個時間和系統的uptime有關,系統重啟后CACurrentMediaTime()會被重置. 就和座標存在相對座標一樣,不同的實現了CAMediaTiming協議的存在層級關系的對象也存在相對時間,經常需要進行時間的轉換,CALayer提供了兩個時間轉換的方法:
    - (CFTimeInterval)convertTime:(CFTimeInterval)t fromLayer:(CALayer *)l;- (CFTimeInterval)convertTime:(CFTimeInterval)t toLayer:(CALayer *)l;
    現在來重點研究CAMediaTiming協議中幾個重要的屬性.

  • beginTime
    無論是圖層還是動畫,都有一個時間線Timeline的概念,他們的beginTime是相對于父級對象的開始時間. 雖然蘋果的文檔中沒有指明,但是通過代碼測試可以發現,默認情況下所有的CALayer圖層的時間線都是一致的,他們的beginTime都是0,絕對時間轉換到當前Layer中的時間大小就是絕對時間的大小.所以對于圖層而言,雖然創建有先后,但是他們的時間線都是一致的(只要不主動去修改某個圖層的beginTime),所以我們可以想象成所有的圖層默認都是從系統重啟后開始了他們的時間線的計時.
    但是動畫的時間線的情況就不同了,當一個動畫創建好,被加入到某個Layer的時候,會先被拷貝一份出來用于加入當前的圖層,在CA事務被提交的時候,如果圖層中的動畫的beginTime為0,則beginTime會被設定為當前圖層的當前時間,使得動畫立即開始.如果你想某個直接加入圖層的動畫稍后執行,可以通過手動設置這個動畫的beginTime,但需要注意的是這個beginTime需要為 CACurrentMediaTime()+延遲的秒數,因為beginTime是指其父級對象的時間線上的某個時間,這個時候動畫的父級對象為加入的這個圖層,圖層當前的時間其實為[layer convertTime:CACurrentMediaTime() fromLayer:nil],其實就等于CACurrentMediaTime(),那么再在這個layer的時間線上往后延遲一定的秒數便得到上面的那個結果.

  • timeOffset
    這個timeOffset可能是這幾個屬性中比較難理解的一個,官方的文檔也沒有講的很清楚. local time也分成兩種一種是active local time 一種是basic local time.timeOffset則是active local time的偏移量. 你將一個動畫看作一個環,timeOffset改變的其實是動畫在環內的起點,比如一個duration為5秒的動畫,將timeOffset設置為2(或者7,模5為2),那么動畫的運行則是從原來的2秒開始到5秒,接著再0秒到2秒,完成一次動畫.

  • speed
    speed屬性用于設置當前對象的時間流相對于父級對象時間流的流逝速度,比如一個動畫beginTime是0,但是speed是2,那么這個動畫的1秒處相當于父級對象時間流中的2秒處. speed越大則說明時間流逝速度越快,那動畫也就越快.比如一個speed為2的layer其所有的父輩的speed都是1,它有一個subLayer,speed也為2,那么一個8秒的動畫在這個運行于這個subLayer只需2秒(8 / (2 * 2)).所以speed有疊加的效果.

  • fillMode
    fillMode的作用就是決定當前對象過了非active時間段的行為. 比如動畫開始之前,動畫結束之后。如果是一個動畫CAAnimation,則需要將其removedOnCompletion設置為NO,要不然fillMode不起作用. 下面來講各個fillMode的意義 kCAFillModeRemoved 這個是默認值,也就是說當動畫開始前和動畫結束后,動畫對layer都沒有影響,動畫結束后,layer會恢復到之前的狀態 kCAFillModeForwards 當動畫結束后,layer會一直保持著動畫最后的狀態 kCAFillModeBackwards 這個和kCAFillModeForwards是相對的,就是在動畫開始前,你只要將動畫加入了一個layer,layer便立即進入動畫的初始狀態并等待動畫開始.你可以這樣設定測試代碼,將一個動畫加入一個layer的時候延遲5秒執行.然后就會發現在動畫沒有開始的時候,只要動畫被加入了layer,layer便處于動畫初始狀態 kCAFillModeBoth 理解了上面兩個,這個就很好理解了,這個其實就是上面兩個的合成.動畫加入后開始之前,layer便處于動畫初始狀態,動畫結束后layer保持動畫最后的狀態.
    其他的一些參數都是比較容易理解的.
    實際應用
    參見蘋果官方 QA1673 How to pause the animation of a layer tree

-(void)pauseLayer:(CALayer*)layer{ 
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; layer.speed = 0.0; layer.timeOffset = pausedTime;
}
-(void)resumeLayer:(CALayer*)layer{
CFTimeInterval pausedTime = [layer timeOffset]; layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0.0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}

三: 顯式動畫Animation

當需要對非Root Layer進行動畫或者需要對動畫做更多自定義的行為的時候,就必須使用到顯式動畫了,顯式動畫的基類為CAAnimation,常用的是CABasicAnimation,CAKeyframeAnimation有時候還會使用到CAAnimationGroup,CATransition(注意不是CATransaction,Transition是過渡的意思).

集成鏈

1):基礎動畫 CABasicAnimation

  • 原理屬性介紹:
    CABasicAnimation 不管是CABasicAnimation還是CAKeyframeAnimation都是繼承于CAPropertyAnimation.



    CABasicAnimation有三個比較重要的屬性,fromValue,toValue,byValue,這三個屬性都是可選的,但不能同時多于兩個為非空.最終都是為了確定animation變化的起點和終點.Setting Interpolation Values詳細介紹了這個三個值的各種情況以及用途. 設置了動畫的起點和終點之后,中間的值都是通過插值方式計算出來的.插值計算的結果由timingFunction指定,默認timingFunction為nil,會使用liner的,也就是變化是均勻的.

  • Timing Function的作用
    Timing Function的會被用于變化起點和終點之間的插值計算.形象點說是Timing Function決定了動畫運行的節奏(Pacing),比如是均勻變化(相同時間變化量相同),先快后慢,先慢后快還是先慢再快再慢.
    時間函數是使用的一段函數來描述的,橫座標是時間t取值范圍是0.0-1.0,縱座標是變化量x(t)也是取值范圍也是0.0-1.0 假設有一個動畫,duration是8秒,變化值的起點是a終點是b(假設是透明度),那么在4秒處的值是多少呢? 可以通過計算為 a + x(4/8) * (b-a), 為什么這么計算呢?講實現的時間映射到單位值的時候4秒相對于總時間8秒就是0.5然后可以得到0.5的時候單位變化量是 x(0.5), x(0.5)/1 = 實際變化量/(b-a), 其中b-a為總變化量,所以實際變化量就是x(0.5) * (b-a) ,最后4秒時的值就是 a + x(0.5) * (b-a),所以計算的本質是映射.
    Timing Function對應的類是CAMediaTimingFunction,它提供了兩種獲得時間函數的方式,一種是使用預定義的五種時間函數,一種是通過給點兩個控制點得到一個時間函數. 相關的方法為

+ (id)functionWithName:(NSString *)name;

+ (id)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

- (id)initWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

五種預定義的時間函數名字的常量變量分別為

kCAMediaTimingFunctionLinear, 
kCAMediaTimingFunctionEaseIn, 
kCAMediaTimingFunctionEaseOut, 
kCAMediaTimingFunctionEaseInEaseOut, 
kCAMediaTimingFunctionDefault. 

下圖展示了前面四種Timing Function的曲線圖,橫座標表示時間,縱座標表示變化量,這點需要搞清楚(并不是平面座標系中xy).



自定義的Timing Function的函數圖像就是一條三次貝塞爾曲線Cubic Bezier Curve,貝塞爾曲線的優點就是光滑,用在這里就使得變化顯得光滑.一條三次貝塞爾曲線可以由起點終點以及兩個控制點決定.
上面的kCAMediaTimingFunctionDefault對應的函數曲線其實就是通過[(0.0,0.0), (0.25,0.1), (0.25,0.1), (1.0,1.0)]這四個點決定的三次貝塞爾曲線,頭尾為起點和終點,中間的兩個點是控制點.


上圖中P0是起點,P3是終點,P1和P2是兩個控制點

如果時間變化曲線既不是直線也不是貝塞爾曲線,而是自定義的,又或者某個圖層運動的軌跡不是直線而是一個曲線,這些是基本動畫無法做到的,所以引入下面的內容,CAKeyframeAnimation,也即所謂的關鍵幀動畫.

  • 代碼示例:
    CABasicAnimation * animation = [CABasicAnimation animation];
    animation.keyPath = @"position";
    animation.duration = 2;
    animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(80, 80)];
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 30)];
     animation.repeatCount = CGFLOAT_MAX;
    //是否動畫完成就移除模型圖層
    animation.removedOnCompletion = NO;
    //動畫填充模式
    animation.fillMode = kCAFillModeForwards;
    [_myview.layer addAnimation:animation forKey:nil];

 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];  
    animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(_demoView.center.x, _demoView.center.y)];  //可以省略...  
    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(270, 410)];  
    animation.duration = 3.0f;  
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];    //動畫速度設置  
      
    [_demoView.layer addAnimation:animation forKey:nil];  

2)關鍵幀動畫 CAKeyframeAnimation

  • 1、原理和屬性:
    任何動畫要表現出運動或者變化,至少需要兩個不同的關鍵狀態,而中間的狀態的變化可以通過插值計算完成,從而形成補間動畫,表示關鍵狀態的幀叫做關鍵幀.


CABasicAnimation其實可以看作一種特殊的關鍵幀動畫,只有頭尾兩個關鍵幀.

  • CABasicAnimationCAKeyframeAnimation 與CAKeyframeAnimation差異:
    則可以支持任意多個關鍵幀,關鍵幀有兩種方式來指定,使用path或者values,path是一個CGPathRef的值,且path只能對CALayer的 anchorPoint 和 position 屬性起作用,且設置了path之后values就不再起效了.而values則更加靈活. keyTimes這個可選參數可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的.

  • timingFunctions:
    可以通過設置可選參數timingFunctions(CAKeyframeAnimation中timingFunction是無效的)為關鍵幀之間的過渡設置timingFunction,如果values有n個元素,那么timingFunctions則應該有n-1個.但很多時候并不需要timingFunctions,因為已經設置了夠多的關鍵幀了,比如沒1/60秒就設置了一個關鍵幀,那么幀率將達到60FPS,完全不需要相鄰兩幀的過渡效果(當然也有可能某兩幀 值相距較大,可以使用均勻變化或者增加幀率,比如每0.01秒設置一個關鍵幀)

  • calculationMode:
    在關鍵幀動畫中還有一個非常重要的參數,那便是calculationMode,計算模式.其主要針對的是每一幀的內容為一個座標點的情況,也就是對anchorPoint 和 position 進行的動畫.當在平面座標系中有多個離散的點的時候,可以是離散的,也可以直線相連后進行插值計算,也可以使用圓滑的曲線將他們相連后進行插值計算.
    calculationMode目前提供如下幾種模式

kCAAnimationLinear 
kCAAnimationDiscrete 
kCAAnimationPaced 
kCAAnimationCubic 
kCAAnimationCubicPaced
  • kCAAnimationLinear calculationMode`的默認值,表示當關鍵幀為座標點的時候,關鍵幀之間直接直線相連進行插值計算;

  • kCAAnimationDiscrete 離散的,就是不進行插值計算,所有關鍵幀直接逐個進行顯示;

  • kCAAnimationPaced 使得動畫均勻進行,而不是按keyTimes設置的或者按關鍵幀平分時間,此時keyTimes和timingFunctions無效;
    kCAAnimationCubic 對關鍵幀為座標點的關鍵幀進行圓滑曲線相連后插值計算,對于曲線的形狀還可以通過tensionValues,continuityValues,biasValues來進行調整自定義,這里的數學原理是Kochanek–Bartels spline,這里的主要目的是使得運行的軌跡變得圓滑;

  • kCAAnimationCubicPaced 看這個名字就知道和kCAAnimationCubic有一定聯系,其實就是在kCAAnimationCubic的基礎上使得動畫運行變得均勻,就是系統時間內運動的距離相同,此時keyTimes以及timingFunctions也是無效的.

  • 2、代碼示例:

CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
    anima.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
    anima.duration = 2.0f;
      //用系統最大的cgfloat作為重復次數,但是當界面刷新后就沒有動畫效果了,因為沒有加入消息循環隊列,要想實現UI刷新后依然有動畫鮮果建議使用displayLink,原理和NSTimer加入消息循環隊列一樣的
     anima.repeatCount = CGFLOAT_MAX;
 anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//設置動畫的節奏
    anima.delegate = self;//設置代理,可以檢測動畫的開始和結束
    [_demoView.layer addAnimation:anima forKey:@"keyFrameAnimation"];

UIBezierPath *path = [UIBezierPath bezierPath];  
    [path moveToPoint:_demoView.center];    //一定要設置 不然底層的CGPathRef找不到起始點,將會崩潰  
    [path addCurveToPoint:CGPointMake(270, 410) controlPoint1:CGPointMake(0, Screen_Height) controlPoint2:CGPointMake(Screen_Width, 0)];    //以左下角和右上角為控制點  
      
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];  
    animation.path = path.CGPath;  
    animation.duration = 3.0f;  
    animation.removedOnCompletion = NO;  
    animation.fillMode = kCAFillModeForwards;  
      
    [_demoView.layer addAnimation:animation forKey:nil];  

四:動畫組CAAnimationGroup

  • 原理和屬性:
    Group也就是組合的意思,可以保存一組動畫對象,將CAAnimationGroup對象加入圖層后,組中所有動畫對象可以同時并發運行.
    animations屬性:用來保存一組動畫對象的NSArray
    注意:默認情況下,一組動畫對象是同時運行的,也 可以通過設置動畫對象的beginTime屬性來更改動畫的開始時間.

  • 代碼示例:

 // 位移動畫
    CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
    anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
    anima1.removedOnCompletion = NO;
    anima1.fillMode = kCAFillModeBoth;
    anima1.beginTime = 2;
    anima1.duration = 2;
    //縮放動畫
    CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    anima2.fromValue = [NSNumber numberWithFloat:0.1f];
    anima2.toValue = [NSNumber numberWithFloat:2.0f];
    anima2.removedOnCompletion = NO;
    anima2.fillMode = kCAFillModeForwards;
    anima2.beginTime = 2;
    //旋轉動畫
    CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    anima3.toValue = [NSNumber numberWithFloat:M_PI*4];
    anima3.removedOnCompletion = NO;
    anima3.fillMode = kCAFillModeForwards;
    //組動畫
//    如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在動畫執行完畢后,圖層會保持顯示動畫執行后的狀態。但在實質上,圖層的屬性值還是動畫執行前的初始值,并沒有真正被改變
    CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
    groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];
    groupAnimation.duration = 4.0f;
    groupAnimation.removedOnCompletion = NO;
    groupAnimation.fillMode = kCAFillModeForwards;
    [_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];
   // 一個layer設定了很多動畫,他們都會同時執行,而且是順序執行。

五:CATransition轉成動畫。

  • 轉場動畫就是給UIView或者CAlayour一個動畫效果而已 和UIView和CAlayour本身沒有任何關聯。

  • 用途:用于視圖或者圖片的切換。

  • 參數說明:

  • type:


//官方推薦的 可用
//kCATransitionFade //淡入淡出 (不支持過渡方向)
//kCATransitionPush, //推擠
//kCATransitionReveal //揭開
//kCATransitionMoveIn //覆蓋
//非官方推薦 謹慎使用,有些不能上線的
//Cube //立方體
//SuckEffect //吮吸
//OglFlip //翻轉
//rippleEffect //波紋
//pageCurl //翻頁
//pageUnCurl //反翻頁
//cameraIrisHollowOpen //開鏡頭 相機鏡頭打開效果(不支持過渡方向)
//cameraIrisHollowClose //關鏡頭 相機鏡頭打開效果(不支持過渡方向)


  • subtype:

CA_EXTERN NSString * const kCATransitionFromRight
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//右
CA_EXTERN NSString * const kCATransitionFromLeft
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//左
CA_EXTERN NSString * const kCATransitionFromTop//頂
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
CA_EXTERN NSString * const kCATransitionFromBottom//底部
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);


  • 代碼示例
    CATransition *animation = [CATransition animation];
    //設置運動時間
    animation.duration = DURATION;
    //設置運動type
    animation.type = kCATransitionMoveIn;//非官方推薦的自能使用字符串@“fade”
    animation.subtype = kCATransitionFromRight;
  
    //設置運動速度
    animation.timingFunction = UIViewAnimationOptionCurveEaseInOut;
    [self.myView.layer addAnimation:animation forKey:@"animation"];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,030評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,310評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,951評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,796評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,566評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,055評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,142評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,303評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,799評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,683評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,899評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,409評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,135評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,757評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,528評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,844評論 2 372

推薦閱讀更多精彩內容