我在iOS上使用块基础API来制作动画。
一个动画有一个完成块,并且在动画结束时调用该块,很好。
但是,当用户滚动(动画在UITableViewCell
上)时,可以多次触发该动画。当发生这种情况时,多次调用完成块。块的finished
参数始终为YES
。
由于动画实际上没有完成(发生了其他动画),我认为finished
参数不是,但事实并非如此。
我错过了什么吗?如何避免多次调用完成块?
答案 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中修复。