1

私はただ楽しみのために試していた何かについて少し混乱しています。animateBars_V1UIImageViewsの配列を使用し、各UIImageViewの高さを変更して、変化する色付きのバーのセットを表示するという小さなメソッドを作成しました。

ここに画像の説明を入力してください

- (void)animateBars_V1 {
    srandom(time(NULL));
    for(UIImageView *eachImageView in [self barArray]) {
        NSUInteger randomAmount = kBarHeightDefault + (random() % 100);

        CGRect newRect;
        CGRect barRect = [eachImageView frame];

        newRect.size.height = randomAmount;
        newRect.size.width = barRect.size.width;
        newRect.origin.x = barRect.origin.x;
        newRect.origin.y = barRect.origin.y - (randomAmount - barRect.size.height);
        [eachImageView setFrame:newRect];
    }
}

これは正常に機能します。次に、ボタンが押されたときのUIActionを含むUIButtonを追加しました。ボタンが押されるたびanimateBars_V1に呼び出され、色付きのバーが更新されます。

- (IBAction)buttonPressed {
    for(int counter = 0; counter<5; counter++) {
        [self animateBars_V1];
        NSLog(@"COUNTER: %d", counter);
    }
}

私の質問はただの楽しみのためです。ボタンを押すたびにanimateBars_V15回電話することにしました。何が起こるかというと、ループが終了するまでバーは変化しません。これにより、次のようになります。

Screen as per storyboard
COUNTER: 0
COUNTER: 1
COUNTER: 2
COUNTER: 3
COUNTER: 4
Screen Updates

これは正しい動作ですか?これはただの楽しみのためだったので、修正や回避策は必要ありません。将来の参考のために何が起こっているのかもっと興味がありました。

4

3 に答える 3

4

animateBars_V1ループ内で複数回呼び出す場合、バーのフレームは複数回設定されますが、レンダリングされる前にanimateBars_V1再度呼び出され、フレームが新しい位置/サイズに設定されます。

レンダリング(drawRect:および関連するメソッド)の呼び出しは、ループが終了するまで発生しません。これはIBActionであるため、必然的にメインスレッドで呼び出されます。つまり、コードが完了するまですべてのレンダリングがブロックされます。

もちろん、これにはいくつかの解決策があります。マルチアニメーションを行う簡単な方法はUIView animateWithDuration:animations:completion:、次のように使用することです。

- (IBAction)buttonPressed {
    [self animateBarsWithCount:5];
}

- (void)animateBarsWithCount:(int)count
{
    [UIView animateWithDuration:.25f animations:^{
        [self animateBars_V1];
    }completion:^(BOOL finished){
        [self animateBarsWithCount:count - 1];
    }];
}

//animateBars_V1 not repeated

もちろん、アニメーションを1回だけ実行したい場合(実際にはアニメーション化されている場合)は、次のように実行する必要があります。

- (IBAction)buttonPressed {
    [UIView animateWithDuration:.25f animations:^{
        [self animateBars_V1];
    } completion:nil];
}
于 2012-12-11T16:22:52.563 に答える
2

CrimsonDiegoは正しい

これで各通話を遅らせることができます:

- (IBAction)buttonPressed {
    for(int counter = 0; counter<5; counter++) {
        float ii = 1.0 * counter / 10;
        [self performSelector:@selector(animateBars_V1) withObject:nil afterDelay:ii];
        //  [self animateBars_V1];
        NSLog(@"COUNTER: %d", counter);
    }
}
于 2012-12-11T16:31:59.630 に答える
0

問題はここにあります

for(int counter = 0; counter<5; counter++) {
    [self animateBars_V1];
    NSLog(@"COUNTER: %d", counter);
}

このforループはナノ秒で実行され、目は1/16秒しか検出できないため、目はその変化に追いつくことができません。5回実行されるタイマーでこのコードを実行できるものをテストするため。

編集 済みメインスレッドをスリープし、すべてが停止するため、スリープ呼び出しを削除しました。したがって、ここでタイマーを使用します

于 2012-12-11T16:29:16.653 に答える