单个UIView上的多个同时UIViewAnimations

目标
在单个UIView上同时播放多个动画。
问题
据我所知,这是不可能的。 每个动画必须按顺序发生,不能重叠。

本质上,我想要一个UIView垂直动画,同时水平动画。 因为我正在使用UIViewAnimationOptionRepeat ,所以我无法在onCompletion中嵌套任何其他动画这是我想要的工作,但不是:

[UIView animateWithDuration:duration delay:kANIMATION_DELAY options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{ object.frame = CGRectMake(object.frame.origin.x + 40, object.frame.origin.y, object.frame.size.width, object.frame.size.height); [UIView animateWithDuration:duration delay:kANIMATION_DELAY options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{ object.frame = CGRectMake(object.frame.origin.x, object.frame.origin.y - 40, object.frame.size.width, object.frame.size.height); } completion:^(BOOL finished) { }]; } completion:^(BOOL finished) { }]; 

答案不是使用UIViewAnimation块而是使用CABasicAnimations 。 使用它们,您可以分别操纵中心坐标(x,y)。 这是我的代码现在的样子:

  UIView *view = views[i]; // Add the horizontal animation CABasicAnimation *horizontal = [CABasicAnimation animationWithKeyPath:@"position.x"]; horizontal.delegate = self; horizontal.fromValue = [NSNumber numberWithFloat:25.0]; horizontal.toValue = [NSNumber numberWithFloat:50.0]; horizontal.repeatCount = INFINITY; horizontal.duration = 6; horizontal.autoreverses = YES; horizontal.beginTime = 0; // ignore delay time for now horizontal.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [view.layer addAnimation:horizontal forKey:@"horizontal_animation"]; // Add the vertical animation CABasicAnimation *vertical = [CABasicAnimation animationWithKeyPath:@"position.y"]; vertical.delegate = self; vertical.fromValue = [NSNumber numberWithFloat:100.0]; vertical.toValue = [NSNumber numberWithFloat:400.0]; vertical.repeatCount = INFINITY; vertical.duration = 2; vertical.autoreverses = YES; vertical.beginTime = 0; // ignore delay time for now vertical.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; [view.layer addAnimation:vertical forKey:@"vertical_animation"]; 

这允许我在两个单独的动画中处理重复,持续时间等。 然后,当我的动画结束时,我可以调用follow方法来删除动画。 要么,

  [view.layer removeAllAnimations]; 

或者,如果我想删除更具体的动画,

  [view.layer removeAnimationForKey:@"vertical_animation"]; 

然后,如果您想要在动画开始/停止时进行更多自定义控制,您只需要添加委托方法,如下所示:

  -(void)animationDidStart:(CAAnimation *)anim { // custom code here } -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { // custom code here } 

它非常甜蜜和容易。 希望这有助于任何有类似需求的人。 干杯!