AnimationPlanner
 UIView animations without endlessly nesting in completion closures. Used in some of the more superfluous animations in the OK Video app. Very useful with @warpling‘s CAMediaTimingFunction extensions, giving you all the animation curves you need.
 
How do I do this?
 AnimationPlanner to your project (only SPM is currently officially supported) 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 Sample App available when cloning the repo.
Note: The example shows the custom extension methods for CAMediaTimingFunction mentioned in the intro
Installation
  🛠
   Adding AnimationPlanner as a package dependency
 
- Go to 
File->Add Packages - Paste 
https://github.com/PimCoumans/AnimationPlannerin the search bar and click on "Add Package" - Select the target(s) in which you want to use AnimationPlanner
 
  📦
   Swift Package Manager
 
Manually add AnimationPlanner as a package dependency in package.swift, by updating your package definition with:
  dependencies: [
    .package(name: "AnimationPlanner", url: "https://github.com/PimCoumans/AnimationPlanner.git", .branch("main"))
  ],
And updating your target‘s dependencies property with dependencies: ["AnimationPlanner"]
  🔮
   Future plans
 
While this API removes a lot of unwanted nesting in completion closures when using traditional UIView.animate... calls, a project is never finished and for future versions I have the following plans:
- Cancel running animation sequences. Current idea is returning a 
RunningAnimationobject with acancel()method and information about the state of the animation sequence. - Remove usage of inaccurate 
DispatchQueue.main.asyncAfterfor manually adding delays where needed. - Tidy the API even more by using Swift‘s builder pattern, like we see used in SwiftUI. In practice this would mean removing one more indent in your code!
 - Maybe even allow this package to be used with SwiftUI? No idea how that would work.
 
Got any feedback or suggestions? Please let me know! ✌🏻
