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

rya*_*yan 26 uiviewanimation ios

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

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

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

Sta*_*ash 27

UIView文档:

完成

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

这意味着无法保证仅在动画完成时才执行代码.我建议你检查"已完成"参数作为执行条件.

  • 我过早调用此块的唯一实际体验是动画在完成之前被中断. (2认同)
  • 我有同样的问题。即使动画没有发生,“finished”参数的计算结果为“true”,并且无论我将持续时间设置为多长时间,都会立即调用完成块。 (2认同)

Joh*_*rck 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
    }];
});
Run Code Online (Sandbox Code Playgroud)

  • 作为替代方案,你可以随时调用[containsView layoutIfNeeded]来清除动画堆栈,然后再调用[UIView animateWith .....]. (3认同)

Luk*_*uke 6

如果动画没有效果,也可以提早调用完成功能,例如,将视图的Alpha设置为其已具有的值。