解决方案
解决您的问题的方法是使用UIViewPropertyAnimator 而不是UIView.animate,如下所示:
UIViewPropertyAnimator(duration: 5.0, curve: .easeInOut) {
self.clickButton.center = CGPoint(
x: self.clickButton.center.x,
y:self.clickButton.center.y + 500
)
}.startAnimation()
说明
我运行了一个包含您的代码的演示项目,我发现以下内容。实际上,您可以尝试单击按钮的结束位置BEFORE,它在那里被动画化,并且单击仍然有效。
UIView 可以在后台使用 CoreAnimation(CALayer 动画),并使用像 CABasicAnimation 这样的类,您遇到的同样问题仍然存在。
我不知道问题的确切原因(因为 iOS SDK 是封闭源代码),但这是我的近似值。
更改UIView.animate 块内的clickButton.center 属性会导致基础CALayer 对象的属性发生更改。 CALayer 对象中的更改实际上是为屏幕上的视图设置动画。
但是,触摸手势通常由 UIView 对象处理,因为它们继承自 UIResponder(与 CALayer 不同,后者仅直接继承自 NSObject)。
由于clickButton.center 属性在CALayer 动画完成之前设置为新值,因此触摸手势代码不会“看到”.center 属性的中间值。它只是读取在UIView.animate 块中设置的最终值。这就是为什么我相信在动画播放过程中点击结束位置仍然有效。
使用UIViewPropertyAnimator 可能也会更改实际的UIView 属性。
来自official documentation:
动画师对视图的动画属性进行操作,例如 frame、center、alpha 和 transform 属性,从您提供的块创建所需的动画。
参考文献
如果你想了解更多关于UIViewAnimations 的内部工作原理,有一个很棒的堆栈溢出答案here。
Apple's Official Documentation on CABasicAnimation
Apple's Official Documentation on UIViewPropertyAnimator
Apple's Official Documentation on UIResponder