如何创建一系列以 .curveEaseIn 开头并以 .curveEaseOut 结尾的 UIView 动画,并以稳定的速度移动

问题描述

我编写了以下小演示,通过一次旋转 90° 将 UIView 旋转 360°。这意味着动画有 4 个步骤

我希望它在第一个动画步骤中缓和,在中间的 2 个步骤中以稳定的速度前进,然后在最后一步使用缓出计时,使其滑行停止。代码如下。这是它使用的动画时间:

Animating to  90°,options = curveEaseIn
Animating to 180°,options = curveLinear
Animating to 270°,options = curveLinear
Animating to   0°,options = curveEaseOut

每一步需要 1/2 秒,总持续时间为 2 秒。但是,由于第一个和最后一个步骤需要 1/2 秒,但开始/结束的速度较慢,因此这些动画步骤的“全速”部分明显快于使用线性时序的中间 2 个动画步骤。结果动画不流畅。

是否有一种简单的方法来调整步骤时间,使动画中的每个步骤都以与开始/结束步骤相同的速度运行,并具有缓入/缓出时间?

我想我可以创建一个关键帧动画,其中整个动画使用缓入/缓出时间,动画中的中间步骤使用线性时间。然而,似乎应该有一种简单的方法可以从逐步动画中摆脱出来。

class ViewController: UIViewController {
    
    var rotation: CGFloat = 0
    @IBOutlet weak var rotateableView: RotatableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func handleRotateButton(_ sender: UIButton? = nil) {
        let duration = 0.5
        var optionsValue: (options: UIView.AnimationOptions,optionsName: String) = (.curveLinear,"curveLinear")
        self.rotation = fmod(self.rotation + 90,360)
        sender?.isEnabled = false
        if self.rotation == 0 {
            optionsValue = (.curveEaseOut,"curveEaseOut") // Ending the animatino,so ease out.
        } else if self.rotation == 90 {
            optionsValue = (.curveEaseIn,"curveEaseIn") // Beginning the animation,so ease in
        }
        let rotation = String(format:"%3.0f",self.rotation)
        print("Animating to \(rotation)°,options = \(optionsValue.optionsName)")
        UIView.animate(withDuration: duration,delay: 0,options: optionsValue.options) {
            let angle = self.rotation / 180.0 * CGFloat.pi
            self.rotateableView.transform = CGAffineTransform.init(rotationAngle: angle)
        } completion: { finished in
            if self.rotation != 0 {
                self.handleRotateButton(sender)
            } else {
                self.rotation = 0
                sender?.isEnabled = true
            }
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)