Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS-过早调用UIView animateWithDuration中的完成块_Ios_Uiviewanimation - Fatal编程技术网

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

iOS-过早调用UIView animateWithDuration中的完成块,ios,uiviewanimation,Ios,Uiviewanimation,我试图在选中表格视图单元格时制作一些动画。出于某种原因,完成块的调用太早了。即使将持续时间设置为10秒,也会立即调用完成块 [UIView animateWithDuration:10.0 animations:^{ message.frame = newFrame; } completion:^(BOOL finished) { NSLog(@"DONE???"); }]; 你有没有想过为什么会这样?谢谢。来自: 完成 动画序列结束时要执行的块对象。此块没有返回值,只接受一个

我试图在选中表格视图单元格时制作一些动画。出于某种原因,完成块的调用太早了。即使将持续时间设置为10秒,也会立即调用完成块

[UIView animateWithDuration:10.0 animations:^{
    message.frame = newFrame;
} completion:^(BOOL finished) {
    NSLog(@"DONE???");
}];
你有没有想过为什么会这样?谢谢。

来自:

完成

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


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

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

// 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
    }];
});

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

如果有帮助,请在此发布。在我的例子中,我使用了一个
关键帧
动画,并立即调用了完成块。注意这些概念:

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

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

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


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

此代码在哪里执行?例如,如果在
init
方法中,那就太早了。创建控件后,应在
viewDidLoad
或类似的程序中执行此操作。您还可以检查
finished
参数。哪个值具有finished参数?如果不是,你的动画可能会被打断。很抱歉反应太晚,但多米尼克·桑德的想法是正确的。finished的BOOL值记录为“NO”。因此,为了确保我理解,您是说即使动画没有被显式中断,并且没有被另一个动画替换,完成块仍然可以在实际完成之前被调用?或者这两种情况是你所知道的唯一例外?我对这个块被过早调用的唯一实际体验是动画在结束之前被中断。我在iOS 9.3中遇到了相反的问题-从来没有调用过完成块!有什么线索可以解释为什么会发生这种情况吗?建议“检查'finished'参数作为执行的条件”。谢谢,老兄,我也有同样的问题。“finished”参数的计算结果为
true
,即使动画没有出现,并且无论我将持续时间设置为多长,都会立即调用完成块。或者,在调用[UIView animateWith…”之前,您可以始终调用[containingView LayoutFneeded]清除动画堆栈值得思考。虽然不太漂亮,但这是唯一一个解决方案,可以在关闭转换后制作动画。Tanks,我在昨天self.leftViewHeightConstraint.constant=0 self.leftView.superview?.layoutIfNeeded()print(“size(self.tableView.frame.height)”)UIView.animate中寻找解决方案(持续时间:30,延迟:0.5,选项:[.curveEaseOut],动画:{self.leftViewHeightConstraint.constant=self.tableView.frame.height self.leftView.superview?.layoutIfNeeded()},完成:{finished in print(“动画完成”)}//它总是在动画完成中运行