⛓ Chain multiple UIView
animations without endless closure nesting. Create your animation sequence all on the same indentation level using a clear, concise syntax.
🤹 Used for all exuberant animations in OK Video 📲
📖 Check out the documentation to get up to speed, or read on to see a little example.
📦 Add AnimationPlanner
to your project (using Swift Package manager) and start typing AnimationPlanner.plan
to embark on your animation journey. Like what‘s happening in the code below.
AnimationPlanner.plan {
Animate(duration: 0.32, timingFunction: .quintOut) {
view.alpha = 1
view.center.y = self.view.bounds.midY
}
Wait(0.2)
Animate(duration: 0.32) {
view.transform = CGAffineTransform(scaleX: 2, y: 2)
view.layer.cornerRadius = 40
view.backgroundColor = .systemRed
}.timingFunction(.quintOut)
Wait(0.2)
AnimateSpring(duration: 0.25, dampingRatio: 0.52) {
view.backgroundColor = .systemBlue
view.layer.cornerRadius = 0
view.transform = .identity
}
Wait(0.58)
Animate(duration: 0.2) {
view.alpha = 0
view.transform = .identity
view.frame.origin.y = self.view.bounds.maxY
}.timingFunction(.circIn)
}.onComplete { finished in
view.removeFromSuperview()
}
The above code results in the following animation sequence. For more examples see the Sample App available when cloning the repo.
Note: The example uses custom extension methods on CAMediaTimingFunction
, included with the framework
- 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
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"]
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:
- Remove usage of inaccurate
DispatchQueue.main.asyncAfter
, currently used to add delays for non-UIView
animations or bridging gaps between steps. - Maybe even allow this package to play more nicely with SwiftUI? No idea what that would look like though, any ideas?
Got any feedback or suggestions? Please let me know! ✌🏻