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つの変換を1つに連結して、1つのアニメーションでスケールと回転をアニメーション化してみてください。

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 に答える