iOS 旋转动画在 CAAnimationGroup 中发生不顺畅

Posted

技术标签:

【中文标题】iOS 旋转动画在 CAAnimationGroup 中发生不顺畅【英文标题】:iOS rotation animation does not happen smoothly in CAAnimationGroup 【发布时间】:2013-01-21 11:38:28 【问题描述】:

我有 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】:

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

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

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

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

编辑:

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

    将每一层动画包裹在[CATransaction begin]/[CATransaction commit]中;

如果没有帮助,

    不要在创建动画后立即设置要设置动画的属性的最终值;而是将其设置在动画委托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];

【讨论】:

sx、sy、sz 的值应该是多少? 我提供了我在缩放动画中提供的值。这使它变得更大,但并没有解决问题。 问题是,对于一个平坦的层(在 xy 平面上),整个事情工作得很好,需要 2*M_PI 旋转。但是,我还有其他 2 层沿 z 轴放置 -60 度和 +60 度,以创建 3D 感觉。当我想分别将它们旋转 +60 度和 -60 度(最终使它们在 xy 平面上变平)时 - 我观察到了这个问题。 很高兴知道。关于故障,请参阅我的最终编辑,希望对您也有用。 谢谢你:只是我之前碰到过这些问题...... :-) 如果你有兴趣,看看这个:developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/…

以上是关于iOS 旋转动画在 CAAnimationGroup 中发生不顺畅的主要内容,如果未能解决你的问题,请参考以下文章

ios多个animation动画执行使用rotateY旋转重叠问题

ios多个animation动画执行使用rotateY旋转重叠问题

IOS旋转设备没有旋转动画

iOS核心动画之图片旋转、脉冲动画、水波纹动画

动画后的iOS旋转手势

iOS核心动画:旋转的锚点不正确