我有一些 UIButtons,我正在无限期地制作动画。这些按钮都添加了 3 个子层,每个子层都有自己的动画。我在 viewDidAppear
上初始化这些动画效果很好——它们淡入并开始旋转。问题是当我转换到一个新 View 时,动画似乎“快速”回到它们的初始状态,然后在转换发生之前回到其他状态。我已经尝试明确删除 viewWillDisappear 上的所有动画,甚至尝试隐藏整个 UIButton 本身,但似乎没有什么可以阻止这种奇怪的捕捉行为的发生。
这是正在发生的事情的 gif(这是我在两个 View 之间来回转换):
func animateRotation() {
// Gets called on viewDidAppear
let rotationRight: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotationRight.toValue = Double.pi * 2
rotationRight.duration = 4
rotationRight.isCumulative = true
rotationRight.repeatCount = Float.greatestFiniteMagnitude
rotationRight.isRemovedOnCompletion = false
rotationRight.fillMode = .forwards
let rotationLeft: CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotationLeft.toValue = Double.pi * -2
rotationLeft.duration = 3
rotationLeft.isCumulative = true
rotationLeft.repeatCount = Float.greatestFiniteMagnitude
rotationLeft.isRemovedOnCompletion = false
rotationLeft.fillMode = .forwards
let circleImage1 = UIImage(named: "circle_1")?.cgImage
circleLayer1.frame = self.bounds
circleLayer1.contents = circleImage1
circleLayer1.add(rotationRight, forKey: "rotationAnimation")
layer.addSublayer(circleLayer1)
let circleImage2 = UIImage(named: "circle_2")?.cgImage
circleLayer2.frame = self.bounds
circleLayer2.contents = circleImage2
circleLayer2.add(rotationLeft, forKey: "rotationAnimation")
layer.addSublayer(circleLayer2)
let circleImage3 = UIImage(named: "circle_3")?.cgImage
circleLayer3.frame = self.bounds
circleLayer3.contents = circleImage3
circleLayer3.add(rotationRight, forKey: "rotationAnimation")
layer.addSublayer(circleLayer3)
}
我会认为像这样简单的东西会在它知道它消失后立即完全隐藏按钮:
override func viewWillDisappear(_ animated: Bool) {
animatedButton.isHidden = true
}
同样有趣的是,如果我让它运行几分钟,这种情况似乎就会停止。这告诉我这可能是某种竞争条件。只是不确定那场比赛可能是什么......
最佳答案
当您使用 UIView 动画集时,它们会将实际状态设置为最终状态,然后开始动画,即:
UIView.animate(withDuration: 1) { view.alpha = 0 }
如果您在动画开始后立即检查 alpha,它已经是 0。
这是 UIView 为您提供的便利,但 CALayer 没有。当你设置一个 CALayer 动画时,你只是在设置动画值,而不是变量的实际值,所以当动画完成时,层会恢复到它的原始值。在动画中间检查图层值,您会看到实际值没有改变;只有表示层中的动画值发生了变化。
如果您想复制 UIView 行为,您需要在动画开始时设置实际的最终值而不是图层,或者在动画结束时使用委托(delegate)来设置它。
关于ios - UIView 动画在转换到新 View 之前快速恢复到原始状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58220477/