我需要链动画,CABasicAnimation或CAAnimationGroup,但我不知道如何做到这一点,唯一的,我做的是,所有的动画执行在同一时间为同一层。
我怎么能这样做呢?
例如,具有其内容的层设置为一个汽车图像:
1:移动X点向右
第二:旋转90ª到左
3:移动X点
第四:缩放层
所有这一切都必须动画在secuencial方式执行,但我不能做到这一点:S
BTW:我不是英语,对不起,如果我改变了我的语法一些错误:d
我需要链动画,CABasicAnimation或CAAnimationGroup,但我不知道如何做到这一点,唯一的,我做的是,所有的动画执行在同一时间为同一层。
我怎么能这样做呢?
例如,具有其内容的层设置为一个汽车图像:
1:移动X点向右
第二:旋转90ª到左
3:移动X点
第四:缩放层
所有这一切都必须动画在secuencial方式执行,但我不能做到这一点:S
BTW:我不是英语,对不起,如果我改变了我的语法一些错误:d
TL;博士:你需要以前完成后手动添加每个动画。
有没有内置的方法来添加顺序动画。 您可以设置每个动画的延迟是所有先前的喧闹的总和,但我不会推荐它。
相反,我将创建所有的动画,并将它们添加到一个可变数组(使用数组作为队列)中,他们都应该运行的顺序。 然后通过设置自己的动画代表对所有的动画,你可以得到animationDidStop:finished:
回调时的动画完成。
在该方法中,你会从数组中删除第一动画(意味着下一个动画),并将其添加到该层。 既然你是代表你会得到第二次的动画时,在这种情况下,一个完成animationDidStop:finished:
回调将再次运行和下一个动画从可变数组删除并添加到该层。
一旦动画的数组为空,所有的动画将有运行。
一些示例代码让你开始。 首先,你设置你所有的动画:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
[animation setToValue:(id)[[UIColor redColor] CGColor]];
[animation setDuration:1.5];
[animation setDelegate:self];
[animation setValue:[view layer] forKey:@"layerToApplyAnimationTo"];
// Configure other animations the same way ...
[self setSequenceOfAnimations:[NSMutableArray arrayWithArray: @[ animation, animation1, animation2, animation3, animation4, animation5 ] ]];
// Start the chain of animations by adding the "next" (the first) animation
[self applyNextAnimation];
然后在委托回调您只需再次申请下一个动画
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished {
[self applyNextAnimation];
}
- (void)applyNextAnimation {
// Finish when there are no more animations to run
if ([[self sequenceOfAnimations] count] == 0) return;
// Get the next animation and remove it from the "queue"
CAPropertyAnimation * nextAnimation = [[self sequenceOfAnimations] objectAtIndex:0];
[[self sequenceOfAnimations] removeObjectAtIndex:0];
// Get the layer and apply the animation
CALayer *layerToAnimate = [nextAnimation valueForKey:@"layerToApplyAnimationTo"];
[layerToAnimate addAnimation:nextAnimation forKey:nil];
}
我使用的是自定义键layerToApplyAnimationTo
使每个动画知道它的层(它只是通过setValue:forKey:
和valueForKey:
大卫什么建议工作正常,但我会建议用不同的方式。
如果所有的动画都是同一层,你可以创建一个动画组,使每个动画有不同的beginTime
,其中第一个动画开始在beginTime
0,每个新的动画之前,动画的总持续时间后开始。
如果你的动画是在不同的层,但是,你不能使用动画组(所有的动画的动画组必须在同一层上采取行动。)在这种情况下,您需要提交不同的动画,每一个都有一个beginTime
是从偏移CACurrentMediaTime()
例如:
CGFloat totalDuration = 0;
CABasicAnimation *animationOne = [CABasicAnimation animationWithKeyPath: @"alpha"];
animationOne.beginTime = CACurrentMediaTime(); //Start instantly.
animationOne.duration = animationOneDuration;
...
//add animation to layer
totalDuration += animationOneDuration;
CABasicAnimation *animationTwo = [CABasicAnimation animationWithKeyPath: @"position"];
animationTwo.beginTime = CACurrentMediaTime() + totalDuration; //Start after animation one.
animationTwo.duration = animationTwoDuration;
...
//add animation to layer
totalDuration += animationTwoDuration;
CABasicAnimation *animationThree = [CABasicAnimation animationWithKeyPath: @"position"];
animationThree.beginTime = CACurrentMediaTime() + totalDuration; //Start after animation three.
animationThree.duration = animationThreeDuration;
...
//add animation to layer
totalDuration += animationThreeDuration;
下面是斯威夫特的解决方案:
var animations = [CABasicAnimation]()
var animation1 = CABasicAnimation(keyPath: "key_path_1")
// animation set up here, I've included a few properties as an example
animation1.duration = 1.0
animation1.fromValue = 1
animation1.toValue = 0
animation1.append(animation1)
var animation2 = CABasicAnimation(keyPath: "key_path_2")
animation2.duration = 1.0
animation2.fromValue = 1
animation2.toValue = 0
// setting beginTime is the key to chaining these
animation2.beginTime = 1.0
animations.append(animation2)
let group = CAAnimationGroup()
group.duration = 2.0
group.repeatCount = FLT_MAX
group.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
group.animations = animations
yourLayer.addAnimation(group, forKey: nil)
无论是大卫的做法或BEGINTIME财产都ok将动画链接。 见http://wangling.me/2011/06/time-warp-in-animation.html -它明确了使用BEGINTIME等CAMediaTiming协议的属性。
使用KVC。 SETVALUE重点为每个动画。 之后,在animationDidStop您可以定义什么动画已经停止,并在下链运行。
- (void)moveXrightAnimation { CABasicAnimation* theAnimation = ... [theAnimation setValue:@"movexright" forKey:@"animationID"]; //animation } - (void)rotate90leftAnimation { CABasicAnimation* theAnimation = ... [theAnimation setValue:@"rotate90left" forKey:@"animationID"]; //animation } - (void)moveXpointAnimation { CABasicAnimation* theAnimation = ... [theAnimation setValue:@"movexpoint" forKey:@"animationID"]; //animation } - (void)scaleAnimation { CABasicAnimation* theAnimation = ... [theAnimation setValue:@"scale" forKey:@"animationID"]; //animation } #pragma mark - CAAnimationDelegate - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { if([[anim valueForKey:@"animationID"] isEqual:@"movexright"]) { [self rotate90leftAnimation]; } if([[anim valueForKey:@"animationID"] isEqual:@"rotate90left"]) { [self moveXpointAnimation]; } if([[anim valueForKey:@"animationID"] isEqual:@"movexpoint"]) { [self scaleAnimation]; } }