Chain multiple UIView animations without endlessly nesting in completion closures
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
- Go to
File
->Add Packages
and select your Project - 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
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