当其他动画开始时,UIView动画完成块触发

时间:2010-10-28 18:22:53

标签: iphone animation uiview ios

我在iOS上使用块基础API来制作动画。

一个动画有一个完成块,并且在动画结束时调用该块,很好。

但是,当用户滚动(动画在UITableViewCell上)时,可以多次触发该动画。当发生这种情况时,多次调用完成块。块的finished参数始终为YES

由于动画实际上没有完成(发生了其他动画),我认为finished参数不是,但事实并非如此。

我错过了什么吗?如何避免多次调用完成块?

3 个答案:

答案 0 :(得分:5)

完成块被多次调用,因为在您的情况下,您的动画会被多次触发。发生的事情是iOS每次被告知时都会调用你的动画块,可能是在一个单独的线程中。然后,对于每个动画,它跟踪其完成,并在完成时调用关联的完成块。所以基本上,你会看到你的完成块多次触发,每次调用动画一次。请注意,与完成块关联的布尔值特定于该完成块,它不以任何方式引用不同的动画。

回顾一下,您所遇到的只是并发的影响。如果这不是您的预期行为,那么您需要相应地修改您的代码。如果您希望您的动画一次触发一个,您可以使用NSLock(NSConditionLock使用关联条件变量进行高级控制),或者,如果您愿意,可以直接使用互斥锁和Posix pthreads库来创建要执行的关键部分以互相排斥的方式。

答案 1 :(得分:2)

不确定何时触发动画以及它们是否循环(如UIActivityView微调器等) - 听起来像是桌面视图滚动的每个像素?

无论如何,也许您可​​以使用UIScrollView委托方法并告诉每个单元格在scrollViewWillBeginDragging:上开始动画,并告诉每个单元格停在scrollViewDidEndDragging:

您可以为isAnimating设置布尔值UITableViewCell,如果当前正在制作动画,则不执行任何操作。

if (isAnimating) {
     // ... do nothing
} else {
     // Start your animation
}

或者坚持使用你现在拥有的任何东西并使用布尔静止,但只有当它当前没有动画时才触发动画。然后在finished参数中,将isAnimating设置为NO

if (isAnimating) {
         // ... do nothing
    } else {
         [UIView animateWithDuration:0.3f
                          animations:^{
                                     // animations...
                                     isAnimating = YES;
                                     }
                          completion:^{
                                     isAnimating = NO;
                                     }
          ];    
}

答案 2 :(得分:0)

我通过查看完成块是否与该块的开头相关来解决了这个问题。

finished参数现在不相关。我已经与Apple沟通了,他们告诉我它已在iOS 4.2中修复。