iOS 是否有等效的 FastOutSlowInInterpolator?

Is there an equivalent of FastOutSlowInInterpolator for iOS?

是否也有 FastOutSlowInInterpolator for iOS? I've recently got my hands on AndroidX and really like this interpolator. I've found the source code 的等价物,但不知道如何将其转换为 iOS 实现。

如果您正在使用 UIViewPropertyAnimator,则您需要的曲线是 .easeInOut,您可以在创建动画器时将其作为 curve 参数传递:

let animator = UIViewPropertyAnimator(duration: 0.4, curve: .easeInOut) {
    // Animations
}

如果对这个系统曲线不满意,可以按照this answer and use this handy website复制FastOutSlowInInterpolator的控制点

FastOutSlowInInterpolator 文档所述:

Interpolator corresponding to fast_out_slow_in. Uses a lookup table for the Bezier curve from (0,0) to (1,1) with control points: P0 (0, 0) P1 (0.4, 0) P2 (0.2, 1.0) P3 (1.0, 1.0)

因此,在您的特定情况下,您正在寻找这样的东西:

let timingParameters = UICubicTimingParameters(
    controlPoint1: CGPoint(x: 0.4, y: 0),
    controlPoint2: CGPoint(x: 0.2, y: 1)
)
let animator = UIViewPropertyAnimator(duration: 0.4, timingParameters: timingParameters)

或者这个:

let animator = UIViewPropertyAnimator(
    duration: 0.4,
    controlPoint1: CGPoint(x: 0.4, y: 0),
    controlPoint2: CGPoint(x: 0.2, y: 1)
) {
    // Animations
}

SwiftUI

在 SwiftUI 中,您可以使用 .animate 修饰符为几乎任何变化设置动画,并且它接受曲线作为参数。我认为 .interpolatingSpring(stiffness: 30, damping: 20) 是您正在寻找的曲线(底部)。

例子

struct ContentView: View {
    @State var isLeading = false

    var body: some View {
        VStack {
            SpacedCircle(isLeading: $isLeading)
                .animation(.linear)

            SpacedCircle(isLeading: $isLeading)
                .animation(.easeIn)

            SpacedCircle(isLeading: $isLeading)
                .animation(.easeOut)

            SpacedCircle(isLeading: $isLeading)
                .animation(.easeInOut)

            SpacedCircle(isLeading: $isLeading)
                .animation(.interactiveSpring(response: 0.27, dampingFraction: 0.5, blendDuration: 0.2))

            SpacedCircle(isLeading: $isLeading)
                .animation(.interpolatingSpring(stiffness: 30, damping: 20))

            Button("Toggle") { isLeading.toggle() }
        }
    }
}

UIKit

您也可以在 UIKit 中实现类似的功能:

例子

    @IBAction func touched(_ sender: UIButton) {
        UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
            self.circleView.transform = .identity
        }
    }

    @IBAction func touchDown(_ sender: Any) {
        UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 3, options: []) {
            self.circleView.transform = CGAffineTransform(translationX: 240, y: 0)
        }
    }