實際開發(fā)中一個物體的運動往往是復(fù)合運動,單一屬性的運動情況比較少,但是屬性動畫每次只能設(shè)置一個屬性進(jìn)行動畫控制(不管是基礎(chǔ)動畫還是關(guān)鍵幀動畫都是如此),這樣一來要做一個復(fù)合運動的動畫就必須創(chuàng)建多個屬性動畫進(jìn)行組合。對于一兩種動畫的組合或許處理起來還比較容易,但是對于更多動畫的組合控制往往會變得很麻煩,動畫組的產(chǎn)生就是基于這樣一種情況而產(chǎn)生的。動畫組是一系列動畫的組合,凡是添加到動畫組中的動畫都受控于動畫組,這樣一來各類動畫公共的行為就可以統(tǒng)一進(jìn)行控制而不必單獨設(shè)置,而且放到動畫組中的各個動畫可以并發(fā)執(zhí)行,共同構(gòu)建出復(fù)雜的動畫效果。
?動畫組使用起來并不復(fù)雜,首先單獨創(chuàng)建單個動畫(可以是基礎(chǔ)動畫也可以是關(guān)鍵幀動畫),然后將基礎(chǔ)動畫添加到動畫組,最后將動畫組添加到圖層即可。
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController () <CAAnimationDelegate>
@property (nonatomic, strong) CALayer *animationCALayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.animationCALayer = [[CALayer alloc] init];
self.animationCALayer.bounds = CGRectMake(0, 0, 40, 40);
self.animationCALayer.position = CGPointMake(150, 150);
self.animationCALayer.contents = (id)[UIImage imageNamed:@"vehicleResource.png"].CGImage;
[self.view.layer addSublayer:self.animationCALayer];
//創(chuàng)建動畫
[self groupAnimation];
}
#pragma mark - 關(guān)鍵幀動畫
- (CAKeyframeAnimation *) translationAnimation {
// 1、創(chuàng)建關(guān)鍵幀動畫并設(shè)置動畫屬性
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// 2、設(shè)置路徑
// 繪制貝塞爾曲線
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.animationCALayer.position.x, self.animationCALayer.position.y); // 移動到起始點
CGPathAddCurveToPoint(path, NULL, -50.0, 200.0, 150.0, 300.0,100.0, 500.0); // 繪制二次貝塞爾曲線
keyframeAnimation.path = path; // 設(shè)置path屬性
CGPathRelease(path); // 釋放路徑對象
[keyframeAnimation setValue:[NSValue valueWithCGPoint:CGPointMake(100, 500)] forKey:@"KCKeyframeAnimationProperty_EndPosition"];
// 3、添加動畫到圖層,添加動畫后就會執(zhí)行動畫
return keyframeAnimation;
}
#pragma mark - 旋轉(zhuǎn)動畫
- (CABasicAnimation *) rotationAnimation {
// 1、創(chuàng)建動畫并指定動畫屬性
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
// 2、設(shè)置動畫屬性初始值、結(jié)束值
// basicAnimation.fromValue = [NSNumber numberWithInt:M_PI_2];
basicAnimation.toValue = [NSNumber numberWithFloat:M_PI_2*3];
//設(shè)置其他動畫屬性
basicAnimation.duration = 6.0;
basicAnimation.autoreverses = false; // 旋轉(zhuǎn)后再旋轉(zhuǎn)到原來的位置
[basicAnimation setValue:[NSNumber numberWithFloat:M_PI_2*3] forKey:@"KCBasicAnimationProperty_ToValue"];
return basicAnimation;
}
#pragma mark 創(chuàng)建動畫組
-(void)groupAnimation{
//1.創(chuàng)建動畫組
CAAnimationGroup *animationGroup=[CAAnimationGroup animation];
//2.設(shè)置組中的動畫和其他屬性
CABasicAnimation *basicAnimation = [self rotationAnimation];
CAKeyframeAnimation *keyframeAnimation = [self translationAnimation];
animationGroup.animations = @[basicAnimation, keyframeAnimation];
animationGroup.delegate = self;
animationGroup.duration = 6.0;//設(shè)置動畫時間,如果動畫組中動畫已經(jīng)設(shè)置過動畫屬性則不再生效
animationGroup.beginTime = CACurrentMediaTime() + 10;//延遲五秒執(zhí)行
//3.給圖層添加動畫
[self.animationCALayer addAnimation:animationGroup forKey:nil];
}
#pragma mark - 代理方法
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
CAAnimationGroup *animationGroup = (CAAnimationGroup *)anim;
CABasicAnimation *basicAnimation = (CABasicAnimation *)animationGroup.animations[0];
CAKeyframeAnimation *keyframeAnimation = (CAKeyframeAnimation *)animationGroup.animations[1];
CGFloat toValue = [[basicAnimation valueForKey:@"KCBasicAnimationProperty_ToValue"] floatValue];
CGPoint endPoint = [[keyframeAnimation valueForKey:@"KCKeyframeAnimationProperty_EndPosition"] CGPointValue];
[CATransaction begin];
[CATransaction setDisableActions:YES];
//設(shè)置動畫最終狀態(tài)
self.animationCALayer.position = endPoint;
self.animationCALayer.transform = CATransform3DMakeRotation(toValue, 0, 0, 1);
[CATransaction commit];
}