8

次の単純なUIImageViewアニメーションがあります。

-(void) setupTheAnimation {
  self.imgView.animationImages = imagesArr;
  [self.imgView setAnimationRepeatCount:-1];
  self.imgView.animationDuration =0.9;
  [self.imgView startAnimating];
  [self performSelector:@selector(stopTheAnimation) withObject:nil afterDelay:4.0];
}

-(void) stopTheAnimation {
  [self.imgView stopAnimating];
}

しかし、アニメーションが停止すると問題が発生します。アニメーションが停止する最後のフレームが何であるかわかりません。そのため、アニメーションの終了はまったくスムーズではありません。

だから私はする必要があります:

1)アニメーションが終了する最後のフレームが何であるかを知っているので、それをアニメーションの最後の画像として設定しました。これにより、スムーズに停止します。

2)このアニメーションを徐々に停止します。つまり、停止するまでの継続時間を変更して、最初に速度を落とし、次に停止します。

これはサンプルプロジェクトへのリンクです。

4

3 に答える 3

2

元の実装でが使用されていることは知っていますが、継続的に可変の期間で直接animationImages使用する方法がわかりません。ただし、これは自分で実装するための非常に単純な機能です。その場合、配列内の画像間の動的な継続時間の値をコーディングできます。animationImages

次のコードでは、カスタムステッピング関数に置き換えて、停止が要求されたanimationImagesの期間を動的に調整します。これは、ハードエンド時間を指定した元のコードとは少し異なることに注意してください。このコードは、ギアスピンが減速し始めるタイミングを指定します。

本当にハードなアニメーション期間がある場合は、stopTheAnimation選択した減速係数を考慮して呼び出しを調整できます(減速中は、ステップが指定されたしきい値より遅くなるまで、期間をステップごとに10%増やすだけです)。

// my animation stops when the step duration reaches this value:
#define STOP_THRESHOLD_SECONDS 0.1f
#define NUM_IMAGES 35

@implementation ViewController
{
    NSMutableArray *imagesArr;
    int currentImage;
    BOOL stopRequested;
    NSTimeInterval duration;
}

-(void) setupTheAnimation {

    stopRequested = NO;
    currentImage = 0;
    duration = 0.9f / NUM_IMAGES;
    [self stepThroughImages];

    [self performSelector:@selector(stopTheAnimation) withObject:nil afterDelay:4.0];
}

- (void) stepThroughImages {

    self.imgView.image = [imagesArr objectAtIndex: currentImage];

    if (currentImage == NUM_IMAGES - 1) {
        currentImage = 0;
    } else {
        currentImage++;
    }

    if (stopRequested && duration < STOP_THRESHOLD_SECONDS) {
        // we're slowing down gradually
        duration *= 1.1f;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [self stepThroughImages];
        });
    } else if (!stopRequested) {
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC));
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [self stepThroughImages];
        });
    }
}

-(void) stopTheAnimation {
    stopRequested = YES;
}
于 2013-02-24T12:26:57.630 に答える
0

私はこれをブロックを使用することによってのみ知っていますが、これを行う方法は次のとおりです。

    [UIImageView animateWithDuration:0.9f delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{

                // animate what you want
                self.imgView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);

            } completion:^(BOOL finished){

                // animation is completed
                self.imgView.image = image;

            }];

オプション'UIViewAnimationOptionCurveEaseOut'は、アニメーションを徐々に停止するはずです。他のオプションを試して、自分で効果を確認することもできます。

于 2013-02-18T16:19:13.497 に答える
0

あなたのアプローチには問題があります:1秒あたりのフレーム数は一定ではありません(あなたは時間を遅くします)。

フレームアニメーションが必要ですか?

あなたのアニメーションが幾何学的(アフィン)変換で達成できるなら、それは本当に良いでしょう。

アニメーションを次の組み合わせで実行できる場合:

  • 翻訳
  • 回転
  • スケーリング

次に、これはアフィン変換です。

于 2013-02-24T17:23:44.310 に答える