iOS旋转动画在CAAnimationGroup中不会顺利进行

时间:2013-01-21 11:38:28

标签: iphone ios rotation caanimation cabasicanimation

我在一组中运行了3个动画:位置,比例和旋转

但是我的旋转动画并不顺利。它在开始时突然发生,而其他动画则顺利发生。

这是我的代码:

//CABasicAnimation *scaleAnimation
//CABasicAnimation *moveAnimation
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
rotationAnimation.autoreverses = NO;  

rotationAnimation.toValue = [NSNumber numberWithFloat: 0];//-(M_PI/3)];
//below line shows the end state, if removed, the layer will assume its initial position after animation, something which I don't want.
[layer setTransform:CATransform3DMakeRotation(0, 0, 1, 0)];    

CAAnimationGroup *theGroup = [CAAnimationGroup animation];
//Code for adding all 3 animations to the group

编辑:

rotationAnimation.toValue = [NSNumber numberWithFloat: - (M_PI / 3)];

从动画声明的位置删除最终变换值,并将其添加到委托中。 (请注意,对于动画组,单个动画代表不会被击中,只有组代表工作)。

在代表下:

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{   
    NSString * animName = [theAnimation valueForKey:@"animationName"];
    CALayer* layer = [theAnimation valueForKey:@"animationLayer"];

    if ([animName isEqualToString:@"MoveZoomOut"])
    {

       if ([layer.name isEqualToString:@"Layer1"])
          [layer setTransform:CATransform3DMakeRotation(-M_PI/3, 0, 1, 0)];
       else if ([layer.name isEqualToString:@"Layer2"])
          [layer setTransform:CATransform3DMakeRotation(M_PI/3, 0, 1, 0)];
       else
          [layer setTransform:CATransform3DMakeRotation(0, 0, 1, 0)];
    }

    if ([layer respondsToSelector:@selector(setContentsScale:)])
    {
        layer.contentsScale = [UIScreen mainScreen].scale;
    }
}

1 个答案:

答案 0 :(得分:1)

  

我在一组中运行了3个动画:位置,比例和旋转

我怀疑,既然您通过transform属性设置了缩放和旋转动画,则可能会发生冲突。

尝试通过将2个变换连接成一个动画,在单个动画中设置缩放和旋转动画:

CATransform3D t = CATransform3DMakeRotation(0, 0, 1, 0)];
[layer setTransform:CATransform3DScale(t, sx, sy, sz)]; 

编辑:

我知道发生的事情是非常不寻常的,所以我会给你一些关于技巧的提示,这些技巧在很多时候帮助了我。据我所知,你有3层动画。

  1. [CATransaction begin]/[CATransaction commit];
  2. 中打包每个图层动画

    如果这没有帮助,

    1. 在创建动画本身后,不要设置要动画的属性的最终值;而是将其设置在动画委托animationDidStop:finished:方法中。
    2. 换句话说,给出你的代码:

      CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
      rotationAnimation.autoreverses = NO;  
      
      rotationAnimation.toValue = [NSNumber numberWithFloat: 0];//-(M_PI/3)];
      //below line shows the end state, if removed, the layer will assume its initial position after animation, something which I don't want.
      [layer setTransform:CATransform3DMakeRotation(0, 0, 1, 0)];    
      
      CAAnimationGroup *theGroup = [CAAnimationGroup animation];
      

      不要在那里做[layer setTransform:CATransform3DMakeRotation(0, 0, 1, 0)];。相反,请在:

      - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag {
         [layer setTransform:CATransform3DMakeRotation(0, 0, 1, 0)];
      }
      

      由于您将有多个动画(并且可能会为所有动画使用相同的委托),因此您需要一种方法来判断animationDidStop:方法引用的动画。为此目的,你可以做到,例如:

      //-- se the delegate
      rotationAnimation.delegate = self;
      [rotationAnimation setValue:layer forKey:@"animationLayer"];
      

      并在委托方法中:

      - (void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag {
      
         [CATransaction begin];
         [CATransaction setDisableActions:YES];
      
         CALayer* layer = [anim valueForKey:@"animationLayer"];
         layer.transform = ...;
      
         [CATransaction commit];
      
      }
      

      我知道这似乎有点做作。它是。但这是我能解决类似于你报道的问题的唯一方法。

      希望这有帮助。

      编辑:

      对于使用animationDidStop:时的故障,请尝试将animationDidStop:内容包装在:

      [CATransaction begin];
      [CATransaction setDisableActions:YES];
      ...
      [CATransaction commit];