在iOS中,圖形可分為以下幾個層次:

越上層,封裝程度越高,動畫實現越簡潔越簡單,但是自由度越低;反之亦然。本文着重介紹Core Animation層的基本動畫實現方案。
在iOS中,展示動畫可以類比於顯示生活中的“拍電影”。拍電影有三大要素:演員+劇本+開拍,概念類比如下:
演員--->CALayer,規定電影的主角是誰 劇本--->CAAnimation,規定電影該怎么演,怎么走,怎么變換 開拍--->AddAnimation,開始執行
一、概念介紹
1.1CALayer是什么呢?
CALayer是個與UIView很類似的概念,同樣有layer,sublayer...,同樣有backgroundColor、frame等相似的屬性,我們可以將UIView看做一種特殊的CALayer,只不過UIView可以響應事件而已。一般來說,layer可以有兩種用途,二者不互相沖突:一是對view相關屬性的設置,包括圓角、陰影、邊框等參數,更詳細的參數請點擊這里;二是實現對view的動畫操控。因此對一個view進行core animation動畫,本質上是對該view的.layer進行動畫操縱。
1.2CAAnimation是什么呢?
CAAnimation可分為四種:
- 1.CABasicAnimation
- 通過設定起始點,終點,時間,動畫會沿着你這設定點進行移動。可以看做特殊的CAKeyFrameAnimation
- 2.CAKeyframeAnimation
- Keyframe顧名思義就是關鍵點的frame,你可以通過設定CALayer的始點、中間關鍵點、終點的frame,時間,動畫會沿你設定的軌跡進行移動
- 3.CAAnimationGroup
- Group也就是組合的意思,就是把對這個Layer的所有動畫都組合起來。PS:一個layer設定了很多動畫,他們都會同時執行,如何按順序執行我到時候再講。
- 4.CATransition
- 這個就是蘋果幫開發者封裝好的一些動畫
二、動手干活
實踐出真知,看個例子就知道:
比如我們想實現一個類似心跳的縮放動畫可以這么做,分為演員初始化、設定劇本、電影開拍三個步驟:
- (void)initScaleLayer
{
//演員初始化
CALayer *scaleLayer = [[CALayer alloc] init];
scaleLayer.backgroundColor = [UIColor blueColor].CGColor;
scaleLayer.frame = CGRectMake(60, 20 + kYOffset, 50, 50);
scaleLayer.cornerRadius = 10;
[self.view.layer addSublayer:scaleLayer];
[scaleLayer release];
//設定劇本
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
scaleAnimation.toValue = [NSNumber numberWithFloat:1.5];
scaleAnimation.autoreverses = YES;
scaleAnimation.fillMode = kCAFillModeForwards;
scaleAnimation.repeatCount = MAXFLOAT;
scaleAnimation.duration = 0.8;
//開演
[scaleLayer addAnimation:scaleAnimation forKey:@"scaleAnimation"];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self initScaleLayer];
}
效果請參考附圖中的藍色方塊。其他效果可以依葫蘆畫瓢輕松實現。想要實現不同的效果,最關鍵的地方在於CABasicAnimation對象的初始化方式中keyPath的設定。在iOS中有以下幾種不同的keyPath,代表着不同的效果:

此外,我們還可以利用GroupAnimation實現多種動畫的組合,在GroupAnimation中的各個動畫類型是同時進行的。
- (void)initGroupLayer
{
//演員初始化
CALayer *groupLayer = [[CALayer alloc] init];
groupLayer.frame = CGRectMake(60, 340+100 + kYOffset, 50, 50);
groupLayer.cornerRadius = 10;
groupLayer.backgroundColor = [[UIColor purpleColor] CGColor];
[self.view.layer addSublayer:groupLayer];
[groupLayer release];
//設定劇本
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
scaleAnimation.toValue = [NSNumber numberWithFloat:1.5];
scaleAnimation.autoreverses = YES;
scaleAnimation.repeatCount = MAXFLOAT;
scaleAnimation.duration = 0.8;
CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnimation.fromValue = [NSValue valueWithCGPoint:groupLayer.position];
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(320 - 80,
groupLayer.position.y)];
moveAnimation.autoreverses = YES;
moveAnimation.repeatCount = MAXFLOAT;
moveAnimation.duration = 2;
CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
rotateAnimation.fromValue = [NSNumber numberWithFloat:0.0];
rotateAnimation.toValue = [NSNumber numberWithFloat:6.0 * M_PI];
rotateAnimation.autoreverses = YES;
rotateAnimation.repeatCount = MAXFLOAT;
rotateAnimation.duration = 2;
CAAnimationGroup *groupAnnimation = [CAAnimationGroup animation];
groupAnnimation.duration = 2;
groupAnnimation.autoreverses = YES;
groupAnnimation.animations = @[moveAnimation, scaleAnimation, rotateAnimation];
groupAnnimation.repeatCount = MAXFLOAT;
//開演
[groupLayer addAnimation:groupAnnimation forKey:@"groupAnnimation"];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self initGroupLayer];
}

完整的demo工程點CAAnimationDemo.zip下載
=======================================================
原創文章,轉載請注明 編程小翁@博客園,郵件zilin_weng@163.com,歡迎各位與我在C/C++/Objective-C/機器視覺等領域展開交流!
=======================================================
