⛓ 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
File
-> Add Packages
https://github.com/PimCoumans/AnimationPlanner
in the search bar and click on "Add Package"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:
DispatchQueue.main.asyncAfter
, currently used to add delays for non-UIView
animations or bridging gaps between steps.Got any feedback or suggestions? Please let me know! ✌🏻
link |
Stars: 85 |
Last commit: 5 weeks ago |
Swift 5.8 changed some type-checking logic around result builders, complicating AnimationPlanner’s ‘clever’ logic of allowing some type of animations for both group and sequence animations. Now the following has been updated
@SequenceBuilder
and @GroupBuilder
respectively)Loop
convenience struct and its static method Loop.through()
have been removed, with a build error suggesting other approachesmapAnimations()
is now replaced with mapSequence()
and mapGroup()
. While not as clearly named, the type-checker now clearly knows what to do.for
and for _ in
loops is more encouraged, as the result builder is perfectly capable to handle these.Full Changelog: https://github.com/PimCoumans/AnimationPlanner/compare/1.0.0...v1.1.0
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics