0

我有 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;
    }
}
4

1 回答 1

1

我有 3 个动画在一组中运行:位置、缩放和旋转

我怀疑由于您正在通过transform属性完成缩放和旋转的动画,因此可能会发生冲突。

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

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

编辑:

我知道正在发生的事情很不寻常,所以我会给你一些提示,告诉你一些在几个场合对我有帮助的技巧。我明白,你有 3 层动画。

  1. 将每一层动画包装在[CATransaction begin]/[CATransaction commit];

如果这没有帮助,

  1. 不要在创建动画本身后立即设置要设置动画的属性的最终值;而是在动画委托animationDidStop:finished:方法中设置它。

换句话说,给定您的代码:

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];
于 2013-01-21T12:07:24.677 回答