AnimationPlanner

Chain multiple UIView animations without endlessly nesting in completion closures. Very useful with @warpling‘s CAMediaTimingFunction extensions, giving you all the animation curves you need.

How do I do this?

Add AnimationPlanner to your project (through ? SPM preferably) and use the UIView.animateSteps() method to start adding steps to the provided sequence, like shown below.

UIView.animateSteps { sequence in
    sequence
        .delay(0.35)
        .add(duration: 0.5, timingFunction: .quartOut) {
            view.alpha = 1
            view.center.y = self.view.bounds.midY
        }
        .delay(0.2)
        .add(duration: 0.32, timingFunction: .quintOut) {
            view.transform = CGAffineTransform(scaleX: 2, y: 2)
            view.layer.cornerRadius = 40
            view.backgroundColor = .systemRed
        }
        .delay(0.2)
        .add(duration: 0.12, timingFunction: .backOut) {
            view.backgroundColor = .systemBlue
            view.layer.cornerRadius = 0
            view.transform = .identity
        }
        .delay(0.58)
        .add(duration: 0.2, timingFunction: .circIn) {
            view.alpha = 0
            view.transform = .identity
            view.frame.origin.y = self.view.bounds.maxY
        }
} completion: { finished in
    view.removeFromSuperview()
}

The above code creates the following animation. For more examples see the included sample app.

Installation

Adding AnimationPlanner as a package dependency

  1. Go to File -> Add Packages and select your Project
  2. Paste https://github.com/PimCoumans/AnimationPlanner in the search bar and click on “Add Package”
  3. Select the target(s) in which you want to use AnimationPlanner

Swift Package Manager

Add AnimationPlanner as a package dependency, like shown in the example below:

// swift-tools-version:5.6

import PackageDescription

let package = Package(
  name: "YourProject",
  platforms: [
       .iOS(.v12),
  ],
  dependencies: [
    .package(name: "AnimationPlanner", url: "https://github.com/PimCoumans/AnimationPlanner.git", .branch("main"))
  ],
  targets: [
    .target(name: "YourProject", dependencies: ["AnimationPlanner"])
  ]
)

Future stuff

While this API removes a lot of unwanted nesting in completion closures with traditional UIView.animate... calls, it could be tidied even more by using Swift‘s function builders, like we see used in SwiftUI. For a future release I‘m planning to refactor the code make use of that, hopefully making it look and work a little better.

Got any feedback? Please let me know! ✌?

https://twitter.com/pimcoumans

GitHub

View Github