2

複数をループしてそれぞれにアニメーションを実行しようとしていますUIViewsが、すべてのアニメーションがいつ終了したかを知りたいです。アニメーションのループが終了したときに関数を呼び出す最良の方法は何ですか? 代わりに、すべてが完了するまで待つ方法はありますか?

を使ってみsetAnimationDidStopSelectorましたが、起動しません。この場合、ゲーム ボードからいくつかの「チップ」をフェードアウトさせてから削除します (NumberedChipView は UIView のサブクラスです)。チップがボードから離れるまで、プレイを続けることはできません。

[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDelegate: self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop)]; 

// clear chips 
for (HexagonalTile *aTile in tilesToClear) {

    NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row];

    [UIView animateWithDuration:0.5 delay:0.3 options:UIViewAnimationCurveLinear animations:^{
        chipView.alpha = 0.0; 
    } 
        completion:^(BOOL finished){

         if (finished) {

             [chipView removeFromSuperview]; 
             [self.chipViews removeObject:chipView];

         }
     }]; 
}

[UIView commitAnimations]; 

私もCATransaction無駄にしようとしました:

[CATransaction begin];  

[CATransaction setCompletionBlock:^{
    [self animationFinished]; 
}];  

// clear chips 
for (HexagonalTile *aTile in tilesToClear) {

    NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row];

    [UIView animateWithDuration:0.5 delay:0.3 options:UIViewAnimationCurveLinear animations:^{
        chipView.alpha = 0.0; 
    } 
        completion:^(BOOL finished){

         if (finished) {

             [chipView removeFromSuperview]; 
             [self.chipViews removeObject:chipView];

             //NSLog(@"clearing finished"); 
         }
     }]; 
}

[CATransaction commit]; 

アップデート:

セレクターを起動できるようになりましたが、アニメーションのループが終了するのを待ちません。

[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:)];
4

2 に答える 2

2

for ループは、すべてのアニメーションを同じ遅延と同じ期間で起動しているため、すべて同時に開始および終了します。

完了メソッドは、アニメーションごとに 1 回呼び出されます。

コードを少し書き直して、ループに入る前にカウンターをゼロに設定し、各ステップの後にカウンターをインクリメントすることができます。インデックスが配列カウントより小さい場合、nil 完了ブロックを渡します。インデックス == 配列カウントになると、最後のアイテムになるので、最後のアニメーションが完了したときに呼び出すコードを含む完了ブロックを渡します。

このインデックス アプローチを使用して、インデックス値に基づいて遅延量を増やすことで、各アニメーションを異なる時間に開始できることに注意してください。

delay = .3 + (0.5 * index);
于 2012-05-17T23:21:43.467 に答える
0

これが私のために働いたものです。UIView animateWithDuration メソッドが begin/commit セクションに関連付けられていないことに気付きました。むしろ、begin/commit セクションは「暗黙的な」アニメーション操作の領域をマークするため、アニメーション内でプロパティを設定するだけで、暗黙的にアニメーション化されます。

たとえば、以下のアニメーションでは、chipView の alpha プロパティを「0.0」に設定するだけで、chipView (UIView) が暗黙的にアニメーション化されて消えます。

[UIView beginAnimations:@"tilescleared" context:nil]; 
[UIView setAnimationDelegate: self];
[UIView setAnimationDelay:0.3]; 
[UIView setAnimationDuration:0.5]; 
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 

for (HexagonalTile *aTile in tilesToClear) {

    NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row];

    chipView.alpha = 0.0; 

}

[UIView commitAnimations];

次に、私の animationDidStop メソッドで、「クリーンアップ」を行い、スーパービューからチップを削除します。この animationDidStop メソッドは、ループからのすべての chipView アニメーションが終了したときにのみ起動されます。これは、私が把握しようとしていたトリッキーなことです。

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 
{

    if ([animationID isEqualToString:@"tilescleared"]
                  && [finished boolValue]) {

       for (HexagonalTile *aTile in self.animationInfo.tilesToClear) {

           NumberedChipView *chipView = [self chipViewForColumn:aTile.column andRow:aTile.row];

           [chipView removeFromSuperview]; 
           [self.chipViews removeObject:chipView];
       }

   }

}
于 2012-05-20T07:17:35.300 に答える