【问题标题】:Why Is the Final Presentation of the Animation's Result Not What Is Expected?为什么动画的最终呈现结果不是预期的?
【发布时间】:2023-03-14 18:13:01
【问题描述】:

以下 gif 演示了我遇到的动画问题。红色的小视图正在动画化。小的绿色视图标记了初始位置。红色视图向下和向右移动,然后自动反转。最后,回到初始位置后,红色视图向左跳转:我看不懂的就是这个跳转。

这里是代码。动画有两部分:对 Y 位置的初始更改和在中途开始的 X 位置更改。两个动画都是自动反转的。请注意更新模型以反映由自动反转带来的最终视图位置的完成闭包。这一切对我来说似乎都是正确的。为什么要跳到左边?

    @objc private func animate() {

        let center = animationView.center

        let distance: CGFloat = 100
        let down = {
            UIView.setAnimationRepeatAutoreverses(true)
            self.animationView.center.y += distance
        }
        let right = {
            UIView.setAnimationRepeatAutoreverses(true)
            self.animationView.center.x += distance
        }

        let animator = UIViewPropertyAnimator(duration: 2, curve: .linear, animations: down)
        animator.addAnimations(right, delayFactor: 0.5)
        animator.addCompletion { _ in self.animationView.center = center } // Sync up with result of the autoreverse
        animator.startAnimation()
    }
  1. 向左的跳跃似乎是 100 点(与动画位置变化相同)
  2. 问题似乎与动画的第二部分有关。如果我不添加它,而是在第一部分修改 X(修改了 Y),那么一切都很好。
  3. 当动画完成后,我检查红色视图的中心时发现它是“正确的”;它等于根视图的中心。换句话说:模型和演示不匹配???
  4. 当我使用 Xcode 的 Debug View Hierarchy 功能时,红色视图显示为位于屏幕中心

// *************************************************** ******************************

更新#1:动画由两部分组成;上下左右。在这两个部分的每一个中,我都调用了 UIView.setAnimationRepeatAutoreverse。如果我注释掉其中一个或两个自动反转,那么一切都会按预期工作(尽管我没有得到自动反转的效果,但代码的行为是可以理解的)。

// *************************************************** ******************************

更新 #2:来自 Apple 的 UIView.setAnimationRepeatAutoreverse 文档:在 iOS 4.0 及更高版本中不鼓励使用此方法。相反,您应该使用 animate(withDuration:delay:options:animations:completion:) 方法来指定动画和动画选项。

好的。让我们看看还有什么可以用来完成动画第二部分的延迟。

【问题讨论】:

    标签: animation ios13 xcode11


    【解决方案1】:

    终于!

    private func animate() {
    
        let distance: CGFloat = 100
        let down = { self.animationView.center.y += distance }
        let right = { self.animationView.center.x += distance }
    
        let animator = UIViewPropertyAnimator(duration: 2, curve: .linear, animations: down)
        animator.addAnimations(right, delayFactor: 0.5)
        animator.pausesOnCompletion = true
        let observer = animator.observe(\.isRunning, options: [.new] ) { animator, change in
            print("isRunning changed to \(change.newValue!).")
    
            if !animator.isRunning {
                if !animator.isReversed {
                    print("Reversing animation")
                    animator.isReversed = true;
                    animator.startAnimation()
                }
                else {
                    print("Stopping animation")
                    animator.stopAnimation(false)
                    animator.finishAnimation(at: .start)
                }
            }
        }
        animator.addCompletion { position in
            print("Animation completed at \(position). State = \(animator.state).")
            observer.invalidate() // By capturing the observer here in the completion closure we keep it alive for the duration of the animation.
        }
    
        print("\nStarting animation")
        animator.startAnimation()
        print("Animation started")
    }
    

    【讨论】:

      【解决方案2】:

      使用旧版 API

          @objc private func animate() {
      
              let original = animationView.center
      
              let distance: CGFloat = 100
              let down = { self.animationView.center.y += distance }
              let right = { self.animationView.center.x += distance }
      
              let duration: TimeInterval = 2
              UIView.animate(withDuration: duration, delay: 0, options: .autoreverse, animations: down) { _ in self.animationView.center.y = original.y }
              UIView.animate(withDuration: duration/2, delay: duration/2, options: .autoreverse, animations: right) { _ in self.animationView.center.x = original.x }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-01
        • 2012-11-28
        • 2015-09-14
        • 1970-01-01
        • 1970-01-01
        • 2018-02-05
        • 1970-01-01
        • 2020-04-07
        相关资源
        最近更新 更多