轉載自:http://www.huangyibiao.com/archives/229
本教程寫了這個效果圖的demo,同時總結CABasicAnimation的使用方法。
看完gif動畫完,看到了什麼?平移、旋轉、縮放、閃爍、路徑動畫。
實現平移動畫
實現平移動畫,我們可以通過transform.translation
或者水平transform.translation.x
或者垂直平移transform.translation.y
添加動畫。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// 平移動畫
-
(void)baseTranslationAnimation
{
UIView
*springView =
[[UIView
alloc] initWithFrame:CGRectMake(0,
380,
50,
50)];
[self.view addSubview:springView];
springView.layer.borderColor
= [UIColor
greenColor].CGColor;
springView.layer.borderWidth
= 2;
springView.backgroundColor
= [UIColor
redColor];
CABasicAnimation
*animation =
[CABasicAnimation animationWithKeyPath:@"transform.translation"];
animation.duration
= 2;
CGFloat
width =
self.view.frame.size.width;
animation.toValue
= [NSValue valueWithCGPoint:CGPointMake(width
- 50,
0)];
// 指定動畫重複多少圈是累加的
animation.cumulative
= YES;
// 動畫完成是不自動很危險
animation.removedOnCompletion
= NO;
// 設置移動的效果爲快入快出
animation.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
// 設置無限循環動畫
animation.repeatCount
= HUGE_VALF;
// 設置動畫完成時,自動以動畫回到原點
animation.autoreverses
= YES;
// 設置動畫完成時,返回到原點
animation.fillMode
= kCAFillModeForwards;
[springView.layer
addAnimation:animation forKey:@"transform.translation"];
}
|
translation
是平移的意思,大家需要記住它。這裏只是水平移動,其實我們可以直接對transform.translation.x
設置動畫。不過直接使用transform.translation
也是可以的,我們設置y
值爲0就可以了。
首先,我們通過屬性路徑的方法來創建動畫對象:
1
2
3
|
CABasicAnimation *animation
= [CABasicAnimation animationWithKeyPath:@"transform.translation"];
|
我們設置目的地爲水平移動到屏寬再減去控件的寬50,由於我們只是水平移動,垂直方向沒有移動,因此第二個參數設置爲0即可。我們需要明確一點,toValue
這裏是指移動的距離而不是移到這個點:
1
2
3
|
animation.toValue
= [NSValue valueWithCGPoint:CGPointMake(width
- 50,
0)];
|
對於其它屬性的設置,看註釋裏的說明就可以明白了。
旋轉動畫
旋轉動畫需要藉助CATransform3D
這個表示三維空間的結構體,可以X軸旋轉、Y軸旋轉、Z軸旋轉:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// 旋轉動畫
-
(void)baseRotationAnimation
{
UIView
*springView =
[[UIView
alloc] initWithFrame:CGRectMake(0,
240,
50,
50)];
[self.view addSubview:springView];
springView.layer.borderColor
= [UIColor
greenColor].CGColor;
springView.layer.borderWidth
= 2;
springView.backgroundColor
= [UIColor
redColor];
CABasicAnimation
*animation =
[CABasicAnimation animationWithKeyPath:@"transform"];
animation.duration
= 2;
// Z軸旋轉180度
CATransform3D
transform3d =
CATransform3DMakeRotation(3.1415926,
0,
0,
180);
animation.toValue
= [NSValue valueWithCATransform3D:transform3d];
animation.cumulative
= YES;
animation.removedOnCompletion
= NO;
animation.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.repeatCount
= HUGE_VALF;
animation.autoreverses
= YES;
animation.fillMode
= kCAFillModeForwards;
[springView.layer addAnimation:animation
forKey:@"transform"];
}
|
我們通過屬性路徑創建動畫:
1
2
3
|
CABasicAnimation *animation
= [CABasicAnimation animationWithKeyPath:@"transform"];
|
然後通過創建CATransform3D
結構體,指定旋轉的角度爲180度,X、Y軸不旋轉,Z軸旋轉180度:
1
2
3
4
|
CATransform3D transform3d
= CATransform3DMakeRotation(3.1415926,
0,
0,
180);
animation.toValue
= [NSValue valueWithCATransform3D:transform3d];
|
其它屬性設置與平移動畫一樣。
縮放動畫
transform.scale
這個是圖的屬性路徑,設置scale
值就可以達到縮放的效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// 縮放動畫
-
(void)baseScaleAnimation
{
UIView
*springView =
[[UIView
alloc] initWithFrame:CGRectMake(0,
120,
50,
50)];
[self.view addSubview:springView];
springView.layer.borderColor
= [UIColor
greenColor].CGColor;
springView.layer.borderWidth
= 2;
springView.backgroundColor
= [UIColor
redColor];
CABasicAnimation
*animation =
[CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.duration
= 2;
animation.fromValue
= @(1);
animation.toValue
= @(0);
animation.removedOnCompletion
= NO;
animation.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.repeatCount
= HUGE_VALF;
animation.autoreverses
= YES;
animation.fillMode
= kCAFillModeForwards;
[springView.layer addAnimation:animation
forKey:@"transform.scale"];
}
|
我們通過屬性路徑方法創建動畫對象:
1
2
3
|
CABasicAnimation *animation
= [CABasicAnimation animationWithKeyPath:@"transform.scale"];
|
我們設置了初始變換和最終變換爲1和0:
1
2
3
4
|
animation.fromValue
= @(1);
animation.toValue
= @(0);
|
其實由於圖初始狀態值爲正常狀態,沒有任何縮放,因此其值本就是1,所以fromValue
可以不設置的。
閃爍動畫
我們這裏說的閃爍動畫其實就是透明度的變化,當然我們不能通過alpha
值的變化來實現閃爍動畫,因此這個屬性是不具備隱式動畫效果的。不過系統提供了opacity
,我們可以通過這個值的變化來實現閃爍效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// 閃爍動畫
-
(void)baseSpringAnimation
{
UIView
*springView =
[[UIView
alloc] initWithFrame:CGRectMake(0,
50,
50,
50)];
[self.view addSubview:springView];
springView.layer.borderColor
= [UIColor
greenColor].CGColor;
springView.layer.borderWidth
= 2;
springView.backgroundColor
= [UIColor
redColor];
CABasicAnimation
*animation =
[CABasicAnimation animationWithKeyPath:@"opacity"];
animation.duration
= 2;
animation.fromValue
= @(1);
animation.toValue
= @(0);
animation.removedOnCompletion
= NO;
animation.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.repeatCount
= HUGE_VALF;
animation.autoreverses
= YES;
animation.fillMode
= kCAFillModeForwards;
[springView.layer addAnimation:animation
forKey:@"opacity"];
}
|
我們通過屬性路徑opacity
來創建動畫對象,注意不能使用alpha
,否則不會有動畫效果的:
1
2
3
|
CABasicAnimation *animation
= [CABasicAnimation animationWithKeyPath:@"opacity"];
|
我們設置透明度從1->0變換,其它屬性設置與上面平移動畫一樣:
1
2
3
4
|
animation.fromValue
= @(1);
animation.toValue
= @(0);
|
路徑動畫
路徑動畫這裏添加了灰常詳細的註釋說明,幾乎都包含了所有常用的屬性設置了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// 路徑動畫
-
(void)baseAnimation
{
UIView
*animationView
= [[UIView
alloc] initWithFrame:CGRectMake(0,
0,
100,
100)];
animationView.layer.borderWidth
= 2;
animationView.layer.borderColor
= [UIColor
redColor].CGColor;
animationView.backgroundColor
= [UIColor
greenColor];
[self.view addSubview:animationView];
// 添加動畫
CABasicAnimation
*animation =
[CABasicAnimation animationWithKeyPath:@"position"];
// 起點,這個值是指position,也就是layer的中心值
animation.fromValue
= [NSValue valueWithCGPoint:CGPointMake(50,
50)];
// 終點,這個值是指position,也就是layer的中心值
animation.toValue
= [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width
- 50,
self.view.bounds.size.height
- 100)];
// byValue與toValue的區別:byValue是指x方向再移動到指定的寬然後y方向移動指定的高
// 而toValue是整體移動到指定的點
// animation.byValue = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width - 50 - 50,
// self.view.bounds.size.height - 50 - 50 - 50)];
// 線性動畫
animation.timingFunction
= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.removedOnCompletion
= NO;
// 設定開始值到結束值花費的時間,也就是動畫時長,單位爲秒
animation.duration
= 2;
// 播放速率,默認爲1,表示常速
// 設置爲2則以2倍的速度播放,同樣設置爲N則以N倍速度播放
// 如果值小於1,自然就是慢放
animation.speed
= 0.5;
// 開始播放動畫的時間,默認爲0.0,通常是在組合動畫中使用
animation.beginTime
= 0.0;
// 播放動畫的次數,默認爲0,表示只播放一次
// 設置爲3表示播放3次
// 設置爲HUGE_VALF表示無限動畫次數
animation.repeatCount
= HUGE_VALF;
// 默認爲NO,設置爲YES後,在動畫達到toValue點時,就會以動畫由toValue返回到fromValue點。
// 如果不設置或設置爲NO,在動畫到達toValue時,就會突然馬上返回到fromValue點
animation.autoreverses
= YES;
// 當autoreverses設置爲NO時,最終會留在toValue處
animation.fillMode
= kCAFillModeForwards;
// 將動畫添加到層中
[animationView.layer addAnimation:animation
forKey:@"position"];
}
|
在圖中position
是層相對於父層的中心,而UI控件的center
中心一樣。這裏要整體曲線路徑移動,我們通過position
中心點的變換就可以曲線路徑移動。
這裏設置了CAMediaTiming
協議中的所有屬性,詳細看代碼中的註釋吧,已經很詳細了!
源代碼
小夥伴們可以到github下載源代碼了:CALayerDemo隨手點個star吧~!