3

Is there an equivalent of FastOutSlowInInterpolator for iOS? I've recently got my hands on AndroidX and really like this interpolator. I've found the source code for it too but have no idea how to convert it to iOS implementation.

user246392
  • 2,661
  • 11
  • 54
  • 96
  • May be [curveEaseOut](https://developer.apple.com/documentation/uikit/uiview/animationoptions/1622656-curveeaseout) is what you are looking for? You can use [UIView animate](https://developer.apple.com/documentation/uikit/uiview/1622451-animate) – Bill Oct 20 '20 at 06:02
  • how can I use this with `UIViewPropertyAnimator`? – user246392 Oct 20 '20 at 14:25
  • How about [this answer](https://stackoverflow.com/questions/42488066/adding-curveeasein-to-swift-animation) – Bill Oct 20 '20 at 23:47
  • Can you put an example of the animation you need? (a gif maybe) – Mojtaba Hosseini Oct 26 '20 at 12:10
  • @MojtabaHosseini Look for fast out slow in animation on https://thoughtbot.com/blog/android-interpolators-a-visual-guide – user246392 Oct 28 '20 at 22:26

2 Answers2

1

If you are using UIViewPropertyAnimator the curve that you need is .easeInOut, and you can pass it as curve parameter when you create your animator:

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

If you are not happy with this system curve, you can follow this answer and use this handy website to replicate FastOutSlowInInterpolator's control points.

As FastOutSlowInInterpolator documentation states:

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)

So, in your particular case you are looking for something like this:

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)

or this:

let animator = UIViewPropertyAnimator(
    duration: 0.4,
    controlPoint1: CGPoint(x: 0.4, y: 0),
    controlPoint2: CGPoint(x: 0.2, y: 1)
) {
    // Animations
}
gcharita
  • 7,729
  • 3
  • 20
  • 37
1

SwiftUI

In SwiftUI you can animate almost any change with .animate modifier and it accepts the curve as the argument. I think .interpolatingSpring(stiffness: 30, damping: 20) is the curve that you are looking for (the bottom one).

Examples

Demo

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

You can achieve that similarly in UIKit too:

Example

UIKit Demo

    @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)
        }
    }
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278