等待UIView动画循环完成的最佳方法是什么?

时间:2012-05-16 05:12:44

标签: animation uiview core-animation uiviewanimation catransaction

我正在尝试遍历多个UIViews并在每个setAnimationDidStopSelector上执行动画,但我想知道所有动画何时完成。动画循环结束后调用函数的最佳方法是什么?或者,有没有办法等到所有完成?

我尝试使用[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]; ,但它没有触发。在这种情况下,我通过淡出然后被移除来清除游戏板上的一些“筹码”(NumberedChipView是UIView的子类)。在筹码离开之前,游戏无法继续。

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:)];

更新:

我现在可以启动选择器,但它不会等待动画循环完成。

{{1}}

2 个答案:

答案 0 :(得分:2)

你的for循环以相同的延迟和相同的持续时间触发所有动画,因此它们将同时开始和结束。

您的每个动画都会调用一次完成方法。

您可以稍微重写代码以在进入循环之前将计数器设置为零,并在每个步骤之后递增它。当索引小于数组计数时,传递一个nil完成块。一旦index ==数组计数,你就在最后一个项目上,所以在最后一个动画完成后,用你要调用的代码传入一个完成块。

请注意,您可以使用此索引方法,通过根据索引值增加延迟量,使每个动画在不同时间开始:

delay = .3 + (0.5 * index);

答案 1 :(得分:0)

这是最终为我工作的东西。我意识到UIView animateWithDuration方法没有与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方法中,我执行“清理”并从superview中删除和筹码。这个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];
       }

   }

}