ios - UIView 动画在转换到新 View 之前快速恢复到原始状态

标签 ios swift animation

我有一些 UIButtons,我正在无限期地制作动画。这些按钮都添加了 3 个子层,每个子层都有自己的动画。我在 viewDidAppear 上初始化这些动画效果很好——它们淡入并开始旋转。问题是当我转换到一个新 View 时,动画似乎“快速”回到它们的初始状态,然后在转换发生之前回到其他状态。我已经尝试明确删除 viewWillDisappear 上的所有动画,甚至尝试隐藏整个 UIButton 本身,但似乎没有什么可以阻止这种奇怪的捕捉行为的发生。

这是正在发生的事情的 gif(这是我在两个 View 之间来回转换):

enter image description here

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/

相关文章:

ios - 当子类化(也许?)到另一个节点时,SpriteKit Node 给我 nil | swift

ios - 如何检查 UITextField 的输入是否与数组中的 Core Data 属性匹配?

ios - 查询 Firebase 嵌套数据以检查特定值 - iOS Swift

ios - Scrollview 没有占据自定义选项卡的整个屏幕宽度

ios - 如何从 ScrollView 中删除 subview

ios - 表格单元格中的按钮在点击时不起作用

ios - 在 iOS Swift 中检测设备上正在播放哪个音轨

jquery - 根据溢出宽度确定动画时间

css - 改变动画的方向

java - 如何在没有 Opengl ES 的情况下为对象制作动画?