有一个动画,它将视图从帧CGRect(x: 10, y: 10, width: 100, height: 100)
动画到帧CGRect(x: 10, y: 10, width: 300, height: 300)
。我使用UIViewPropertyAnimator来实现动画,代码如下:
@objc func onTap() {
animator = UIViewPropertyAnimator(duration: 3, curve: .easeIn)
animator.addAnimations {
self.testView.frame = CGRect(x: 10, y: 10, width: 300, height: 300)
}
animator.addCompletion { pos in
print("test view frame:::", self.testView.frame)
print("test view safe frame:::", self.testView.safeAreaLayoutGuide.layoutFrame)
print("test view safe inset:::", self.testView.safeAreaInsets)
print("test view keyboard frame:::", self.testView.keyboardLayoutGuide.layoutFrame)
}
animator.startAnimation()
}
在动画过程中,还有一个按钮用于暂停动画和取消动画,代码如下:
@objc func cancelTheAnimation() {
animator.pauseAnimation()
animator.isReversed = true
let progress = animator.fractionComplete
animator.continueAnimation(
withTimingParameters: UICubicTimingParameters(animationCurve: .linear),
durationFactor: 1 - progress)
}
下面是控制台打印的结果
------- animation completion ------
test view frame::: (10.0, 10.0, 100.0, 100.0)
test view safe frame::: (0.0, 37.0, 100.0, 63.0)
test view safe inset::: UIEdgeInsets(top: 37.0, left: 0.0, bottom: 0.0, right: 0.0)
test view keyboard frame::: (-10.0, 100.0, 390.0, 734.0)
------- animation completion ------
test view frame::: (10.0, 10.0, 100.0, 100.0)
test view safe frame::: (0.0, 37.0, 300.0, 263.0)
test view safe inset::: UIEdgeInsets(top: 37.0, left: 0.0, bottom: 0.0, right: 0.0)
test view keyboard frame::: (-10.0, 300.0, 390.0, 534.0)
第一次的结果是正确的,但是,当我第二次取消动画时,结果是错误的,应该是100而不是300(263 + 37)。
取消动画后,视图的帧将重置回其初始值,但安全区域布局参考线仍保持在由完成的动画设置的目标值。
这是UIKit的bug吗?
如果这不是UIKit的bug,我该如何解决这个问题,使安全区域与动画取消后的视图帧相匹配?
1条答案
按热度按时间jogvjijk1#
这种行为不是UIKit中的bug。当您取消动画并将isReversed属性设置为true时,视图的帧将返回到其原始值
CGRect(x:10,y:10,宽度:100,高度:100)。
然而,视图的安全区域不受动画师的分数完成属性的影响,所以它仍然反映了动画结束时的值。要重置安全区域,您可以设置视图的约束以匹配其帧。我认为这部分将解决您的问题。