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/AnimationPlanner
in 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
RunningAnimation
object with acancel()
method and information about the state of the animation sequence. - Remove usage of inaccurate
DispatchQueue.main.asyncAfter
for 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! ✌🏻