32

当表查看单元格所选时,我正在尝试做一些动画。出于某种原因,完成块被调用得太早了。即使将持续时间设置为 10 秒,完成块也会立即被调用。

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

关于为什么会发生这种情况的任何想法?谢谢。

4

4 回答 4

30

UIView 文档

完成

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

这意味着不能保证只有在动画完成时才会执行代码。我建议您检查“完成”参数作为执行条件。

于 2013-02-03T07:55:19.703 回答
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
    }];
});
于 2014-11-19T22:02:17.427 回答
9

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

于 2017-02-03T16:56:44.337 回答
1

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

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

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

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

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

于 2021-03-16T14:53:43.407 回答