iOS layer層關鍵幀動畫
阿新 • • 發佈:2018-11-21
上次介紹了 UIview的block動畫 ,
這次說一下 view的layer層的關鍵幀動畫
layer層的動畫相對於 view層的動畫 會更輕量。
直接看程式碼 每一個屬性的詳細說明 見程式碼下面的表格
//先建立一個view用於執行動畫
UIView * myview = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
myview.layer.contents = (id)[UIImage imageNamed:@"123"].CGImage;
myview.center = CGPointMake(CGRectGetWidth(self.view .frame)/2, CGRectGetHeight(self.view.frame)/2);
/*
//可以設定 動畫的錨點。用於控制動畫縮放,放大,移動的中心點
//左上角
myview.layer.anchorPoint = CGPointMake(0, 0);
//中心
myview.layer.anchorPoint = CGPointMake(0.5,0.5);
//右下角
myview.layer.anchorPoint = CGPointMake(1, 1);
*/
[self.view addSubview:myview];
//關鍵幀 單一動畫
CAKeyframeAnimation *keyAnima1=[CAKeyframeAnimation animationWithKeyPath:@"transform.rotation" ];
keyAnima1.duration =1;
keyAnima1.values = @[@(0),@(M_PI/4),@(M_PI/2)];
keyAnima1.keyTimes = @[@0.0,@0.1,@1.0];
keyAnima1.fillMode=kCAFillModeForwards;
keyAnima1.removedOnCompletion = NO;
keyAnima1.repeatCount = 1;//或 keyAnima1.repeatDuration = 100;
keyAnima1.beginTime = CACurrentMediaTime() + 1 ;
keyAnima1.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
keyAnima1.delegate = self;
[myview.layer addAnimation:keyAnima1 forKey:@"brushTransformAnimation"];
//關鍵幀 組合動畫
//旋轉動畫
CAKeyframeAnimation *keyAnima_group1=[CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
keyAnima_group1.values = @[@(M_PI/2),@(M_PI),@(M_PI * 2)];;
//位置移動動畫
CAKeyframeAnimation *keyAnima_group2=[CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(myview.center.x,myview.center.y)];
NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(150, 150)];
keyAnima_group2.values= @[value1,value2,value3];
//組合兩個動畫
CAAnimationGroup * g = [CAAnimationGroup animation];
g.animations = @[keyAnima_group1,keyAnima_group2];
g.duration = 3;
g.fillMode=kCAFillModeForwards;
g.removedOnCompletion = NO;
//再上一個動畫執行完 在執行
g.beginTime = CACurrentMediaTime() + 2;
[myview.layer addAnimation:g forKey:@"g"];
//關鍵幀 單一動畫。設定關鍵幀的 path 而不是 value
CAKeyframeAnimation * keyAnima2 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyAnima2.calculationMode = kCAAnimationPaced;
keyAnima2.fillMode = kCAFillModeForwards;
keyAnima2.removedOnCompletion = NO;
keyAnima2.duration = 2;
keyAnima2.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
keyAnima2.beginTime = CACurrentMediaTime() + 5;
CGMutablePathRef curvedPath_3 = CGPathCreateMutable();
CGPathMoveToPoint(curvedPath_3, NULL, 150, 150);
CGPathAddArc(curvedPath_3, NULL, 100, 150, 50, 0 , M_PI*2 , NO);
keyAnima2.path = curvedPath_3;
CGPathRelease(curvedPath_3);
[myview.layer addAnimation:keyAnima2 forKey:@"moveTheSquare"];
基本屬性的說明
屬性 | 說明 |
---|---|
KeyPath | 動畫變化的屬性,如動畫的位置,大小,顏色的變化,詳見“表1” |
duration | 動畫執行的時間 |
repeatCount | 重複次數,無限迴圈可以設定HUGE_VALF或者MAXFLOAT |
repeatDuration | a重複的時間 |
removedOnCompletion | 預設為YES,代表動畫執行完畢後就從圖層上移除,圖形會恢復到動畫執行前的狀態。如果想讓圖層保持顯示動畫執行後的狀態,那就設定為NO,不過還要設定fillMode為kCAFillModeForwards |
fillMode | 決定當前物件在非active時間段的行為。比如動畫開始之前或者動畫結束之,詳見“表2” |
beginTime | 開始時間 |
timingFunction | 速度控制函式,控制動畫執行的節奏 詳見“表3” |
values | NSArray物件。裡面的元素稱為“關鍵幀”(keyframe)。動畫物件會在指定的時間(duration)內,依次顯示values陣列中的每一個關鍵幀 |
keyTimes | 可以為對應的關鍵幀指定對應的時間點,其取值範圍為0到1.0,例如keyAnima1.keyTimes = @[@0.0,@0.1,@0.5,@0.7,@1.0],keyTimes中的每一個時間值都對應values中的每一幀。如果沒有設定keyTimes,各個關鍵幀的時間是平分的,keyTimes 是和 values一起的。 |
path | 可以設定一個CGPathRef、CGMutablePathRef,讓圖層按照路徑軌跡移動。path只對CALayer的anchorPoint和position起作用。如果設定了path,那麼values將被忽略 |
delegate | 動畫代理,動畫開始 和 動畫完成 |
表1
KeyPath屬性的設定詳解:
屬性值 | 說明 |
---|---|
transform.scale | x,y軸同比放大縮小. 對應的 |
transform.scale.x | x軸放大縮小 |
transform.scale.y | y軸放大縮小 |
transform.rotation或transform.rotation.z | 沿z軸旋轉 |
transform.rotation.x | 沿x軸旋轉 |
transform.rotation.y | 沿y軸旋轉 |
margin | 邊距變化 |
backgroundColor | 背景顏色變化 |
cornerRadius | 圓角變化 |
borderWidth | 變得寬度變化 |
bounds | 大小變化 |
contents | 內容變化 |
contentsRect | 內容大小變化 |
frame | 大小變化 |
hidden | 是否顯示 |
mask | mask層變化 |
masksToBounds | ???(有知道的可以評論告訴我) |
shadowColor | 陰影顏色 |
shadowOffset | 陰影位置 |
shadowOpacity | 陰影透明度 |
shadowRadius | 陰影圓角 |
備註:keyPath 對應的 “values” 陣列內大多數存的是 NSNumber 物件 。position ,frame 等 存的是 NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 200)]; 這樣的物件。
表2
fillMode屬性的設定詳解:
屬性值 | 說明 |
---|---|
kCAFillModeRemoved | 這個是預設值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到之前的狀態 |
kCAFillModeForwards | 當動畫結束後,layer會一直保持著動畫最後的狀態 |
kCAFillModeBackwards | 在動畫開始前,只需要將動畫加入了一個layer,layer便立即進入動畫的初始狀態並等待動畫開始。 |
kCAFillModeBoth | 這個其實就是上面兩個的合成.動畫加入後開始之前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態 |
表3
速度控制函式(CAMediaTimingFunction)設定詳解:
屬性值 | 說明 |
---|---|
kCAMediaTimingFunctionLinear | 線性,勻速,給你一個相對靜態的感覺 |
kCAMediaTimingFunctionEaseIn | 漸進,動畫緩慢進入,然後加速離開 |
kCAMediaTimingFunctionEaseOut | 漸出,動畫全速進入,然後減速的到達目的地 |
kCAMediaTimingFunctionEaseInEaseOut | 漸進漸出,動畫緩慢的進入,中間加速,然後減速的到達目的地。這個是預設的動畫行為 |
動畫的代理方法
方法名 | 說明 |
---|---|
– (void)animationDidStart:(CAAnimation *)anim; | 動畫開始時呼叫 |
– (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag; | 動畫結束時呼叫 |
CALayer上動畫的暫停和恢復
#pragma mark 暫停CALayer的動畫
-(void)pauseLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
// 讓CALayer的時間停止走動
layer.speed = 0.0;
// 讓CALayer的時間停留在pausedTime這個時刻
layer.timeOffset = pausedTime;
}
#pragma mark 恢復CALayer的動畫
-(void)resumeLayer:(CALayer*)layer
{
CFTimeInterval pausedTime = layer.timeOffset;
// 1. 讓CALayer的時間繼續行走
layer.speed = 1.0;
// 2. 取消上次記錄的停留時刻
layer.timeOffset = 0.0;
// 3. 取消上次設定的時間
layer.beginTime = 0.0;
// 4. 計算暫停的時間(這裡也可以用CACurrentMediaTime()-pausedTime)
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
// 5. 設定相對於父座標系的開始時間(往後退timeSincePause)
layer.beginTime = timeSincePause;
}