0

キーフレームをアニメーション化するときに、明らかなことを見逃しているようです。MoveMeドキュメントで参照されているApple の を含む多くのコード サンプルを見てきましたが、CAKeyframeAnimation私が見ているものの原因となる不一致は見つかりません。

を作成しCGMutablePathRef、次にを作成しCAKeyframeAnimationて、パスに沿って画像ビューをアニメーション化するように設定します。アニメーション グループが作成されるので、完了したらビューを削除できます。

それでも、私のアニメーションは表示されません。デバイスを回転させるまで。ビューの再レイアウトにより、アニメーションがキックスタートするようです。私は明らかな like[theImageView setNeedsDisplay]または evenを試しsetNeedsLayout、コンテナビューでも試しました。それでも、必要なときにそれを機能させることはできません。デバイスを回転させたときにのみ表示されます。

以下で-cgPathFromArray:は、NSArrayに変換される内部オペコードの を受け取りますCGPathRef。デバイスを回転させると、プログラムされたパスに沿ってアニメーションが表示されるため、正しいことが確認されました。

- (void) animateImage: (NSString*) imageName
               onPath: (NSArray*) path
         withDuration: (NSString*) duration
{
    if (self.sceneView)
    {
        CGMutablePathRef    animationPath   =   [self cgPathFromArray: path];

        if (animationPath)
        {
            UIImage*    image       =   [self findImage: imageName];

            if (image)
            {
                UIImageView*    imageView   =   [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, image.size.width, image.size.height)];

                if (imageView)
                {
                    CAKeyframeAnimation*    keyFrameAnimation   =   [CAKeyframeAnimation animationWithKeyPath: @"position"];

                    imageView.image = image;

                    [self.sceneView addSubview: imageView];

                    keyFrameAnimation.removedOnCompletion   =   YES;
                    keyFrameAnimation.fillMode              =   kCAFillModeForwards;
                    keyFrameAnimation.duration              =   duration.floatValue;
                    keyFrameAnimation.timingFunction        =   [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionLinear];
                    keyFrameAnimation.repeatCount = 0;

                    keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];

                    [keyFrameAnimation setPath: animationPath];

                    //group animation with termination block to cleanup
                    CAAnimationGroup* group     =   [CAAnimationGroup animation];

                    group.duration              =   keyFrameAnimation.duration;
                    group.removedOnCompletion   =   YES;
                    group.fillMode              =   kCAFillModeForwards;
                    group.animations            =   @[keyFrameAnimation];

                    CorpsAnimationCompletionBlock theBlock = ^void(void)
                    {
                        [imageView removeFromSuperview];
                    };

                    [group setValue: theBlock
                             forKey: kCorpsAnimationCompletionBlock];

                    group.delegate = self;

                    [imageView.layer addAnimation: group
                                           forKey:  nil];
                }
            }
        }
    }
}

誰でもこれを手伝うことができますか?

4

1 に答える 1

1

レイヤが可視レイヤ ツリーに追加されるのと同じトランザクションでレイヤにアニメーションを追加しているため、おそらく問題が発生しています。Core Animation は、まだコミットされていないレイヤーにアニメーションをアタッチすることを好みません。[CATransaction flush]レイヤーを追加した後に行うことで、これを回避できる場合があります。

入れ子が多すぎるため、コードがかなり見にくくなっています。読みやすくするために、早期リターンの使用を検討してください。

また、初期化子が作成するのと同じフレームを明示的に作成して-[UIImage initWithImage:]います。

アニメーション グループを使用していて、アニメーションの最後にブロックを実行できるようにデリゲートを設定するだけの場合は、もっと簡単な方法があります。を開始しCATransaction、トランザクションの完了ブロックを設定し、アニメーションを追加して、トランザクションをコミットできます。

したがって:

- (void) animateImage:(NSString *)imageName onPath: (NSArray *)path
    withDuration: (NSString *)duration
{
    if (!self.sceneView)
        return;

    CGMutablePathRef animationPath = [self cgPathFromArray:path];
    if (!animationPath)
        return;

    UIImage *image = [self findImage:imageName];
    if (!image)
        return;

    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    [self.sceneView addSubview: imageView];

    // commit the implicit transaction so we can add an animation to imageView.
    [CATransaction flush];

    [CATransaction begin]; {
        [CATransaction setCompletionBlock:^{
            [imageView removeFromSuperview];
        }];

        CAKeyframeAnimation *animation = [CAKeyframeAnimation
            animationWithKeyPath:@"position"];
        animation.duration = duration.floatValue;
        animation.timingFunction = [CAMediaTimingFunction
            functionWithName:kCAMediaTimingFunctionLinear];
        animation.path = animationPath;
        [imageView.layer addAnimation:animation forKey:animation.keyPath];
    } [CATransaction commit];
}
于 2013-02-27T22:31:17.607 に答える