iOS - UIView animateWithDuration中的完成块过早被调用

时间:2013-02-03 04:51:09

标签: ios uiviewanimation

我正在尝试在选择表格视图单元格时执行一些动画。出于某种原因,完成块过早被调用。即使将持续时间设置为10秒,也会立即调用完成块。

[UIView animateWithDuration:10.0 animations:^{
    message.frame = newFrame;
} completion:^(BOOL finished) {
    NSLog(@"DONE???");
}];

有关为何发生这种情况的任何想法?感谢。

4 个答案:

答案 0 :(得分:26)

来自UIView documentation

  

完成

     

动画序列结束时要执行的块对象。此块没有返回值,并且接受一个布尔参数,该参数指示在调用完成处理程序之前动画是否实际完成。如果动画的持续时间为0,则在下一个运行循环周期开始时执行该块。此参数可能为NULL。

这意味着没有保证代码只在动画完成时执行。我建议你检查一下"完成"参数作为执行条件。

答案 1 :(得分:17)

是。它被称为太早,因为它被某种方式打断了。可能是通过模态演示过渡或者其他东西。根据您的需要,以下可能是您喜欢的解决方案。我们通过手动延迟动画代码的执行来避免冲突:

// To get this in Xcode very easily start typing, "dispatch_aft..."

// Note the "0.2". This ensures the outstanding animation gets completed before we start ours
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [UIView animateWithDuration:1.0 delay:0 options:0 animations:^{
        // Your animation code
    } completion:^(BOOL finished) {
        // Your completion code
    }];
});

答案 2 :(得分:4)

如果动画没有效果,也可以提前调用完成,例如,将视图的alpha设置为已有的值。

答案 3 :(得分:0)

把这个贴在这里以防万一。就我而言,我使用的是 keyframe 动画,并且立即调用了完成块。注意这些概念:

  • duration:整个动画的持续时间,以秒为单位。如果您指定一个负值或 0,则会立即进行更改并且不会产生动画。

  • frameStartTime:开始指定动画的时间。该值必须在 0 到 1 的范围内,其中 0 表示整个动画的开始,1 表示整个动画的结束。例如,对于持续时间为两秒的动画,将开始时间指定为 0.5 会导致动画在整个动画开始后一秒开始执行。

  • frameDuration:动画到指定值的时间长度。该值必须在 0 到 1 的范围内,并指示相对于整个动画长度的时间量。如果您指定的值为 0,则您在动画块中设置的任何属性都会在指定的开始时间立即更新。如果您指定一个非零值,则属性会在该时间段内进行动画处理。例如,对于持续时间为两秒的动画,指定持续时间为 0.5 会导致动画持续时间为一秒。

将这些值中的任何一个设置错误都会影响完成调用的时间。