Search code examples
swiftanimationuiviewuiimagevieweaseinout

Infinite spin animation with "ease in" and "ease out" in Swift?


I want to create a "roulette" (a simple UIImageView with appropriate image) and spin it.

There are similar questions but they describe just how to spin with linear speed by using multiple recursive animation calls. But in my case I need to use easeIn animation on start of spinning and easeOut on stop. So no one answer from those topics help.

How to resolve this issue?

Code Example

func spin() {
        UIView.animate(withDuration: 0.3, delay: 0, options: UIView.AnimationOptions.curveLinear, animations: { () -> Void in
                self.imgViewRoulette.transform = self.imgViewRoulette.transform.rotated(by: .pi / 2)
            }) { (finished) -> Void in
                if finished {
                    self.spin()
                }
            }
    }

Solution

  • The following update to your spin function will start with an easeIn for a 1/4 turn, then do a series of linear 1/4 turns, and then end on an easeOut 1/4 turn.

    func spin(_ iteration: Int = 0, count: Int) {
        let options: UIView.AnimationOptions
        switch iteration {
        case 0:
            options = .curveEaseIn
        case count:
            options = .curveEaseOut
    
        default:
            options = .curveLinear
        }
    
        UIView.animate(withDuration: 0.3, delay: 0, options: options, animations: { () -> Void in
            self.imgViewRoulette.transform = self.imgViewRoulette.transform.rotated(by: .pi / 2)
        }) { (finished) -> Void in
            if iteration < count {
                if finished {
                    self.spin(iteration + 1, count: count)
                }
            }
        }
    }
    

    This can be called with something like:

    someObject.spin(count: 8)