Installation • Usage • Debugging • Animatable Properties • License

Dance is a powerful and straightforward animation framework built upon the new UIViewPropertyAnimator class introduced in iOS 10. With Dance, creating an animation for a view is as easy as calling view.dance.animate { ... }, which can then be started, paused, reversed, scrubbed through, and finished anywhere that the view can be referenced. Dance is especially forgiving, and provides the power that UIViewPropertyAnimator brings to iOS while maintaining ease of use.

Quick Start

import Dance

class MyViewController: UIViewController {

    var circle = UIView(a)override func viewDidLoad() {
        super.viewDidLoad()

        circle.dance.animate(duration: 2.0.curve:.easeInOut) {
            $0.transform = CGAffineTransform(scaleX: 1.5.y: 1.5)
            $0.center = self.view.center
            $0.backgroundColor = .blue
        }.addCompletion { _ in
            print("Animation completed!")
            self.view.backgroundColor = .green
        }.start(after: 5.0)}func pauseAnimation() {
        circle.dance.pause()}}Copy the code

With Dance, you can create referenceable animations attached to views. That means you can call:

  • .pause()
  • .start()
  • .reverse()
  • .setProgress(to:)
  • .finish(at:)

anywhere the view can be referenced.

Installation

platform :ios.'10.0'
target 'ProjectName' do
use_frameworks!

pod 'Dance'

endCopy the code

  • Or drag and drop Dance.swift into your project.

And import Dance in the files you’d like to use it.

Usage

It’s recommended to look through the example project — It has detailed documentation of everything Dance has to offer.

Note: throughout this document, circle will act as the view being animated. You can use Dance on any instance of a UIView or UIView subclass, such as UILabel, UITextField, UIButton, etc.

Using Dance is easy.

  1. Create an animation for a view, and optionally add completion blocks.

  2. Start the animation.

  3. Pause, reverse, or scrub through the animation.

  4. Let the animation complete on its own or manually finish the animation early, triggering any completion blocks.

Creating an Animation

What properties can I animate?

UIKit timing curve

  • easeInOut (slow at beginning and end)
  • easeIn (slow at beginning)
  • easeOut (slow at end)
  • linear
circle.dance.animate(duration: 2.0.curve:.easeInOut) { (make) in
    make.center = newCenter
}Copy the code

. alternatively:

circle.dance.animate(duration: 2.0.curve:.easeInOut) {
    $0.center = newCenter
}Copy the code

Custom Cubic Bézier Timing Curve

let controlPoint1 = CGPoint(x: 0.y: 1)
let controlPoint2 = CGPoint(x: 1.y: 0)

circle.dance.animate(duration: 2.0.controlPoint1: controlPoint1, controlPoint2: controlPoint2) {
    $0.center = newCenter
}Copy the code

Developer.apple.com/videos/play…

Sping-based Timing Information

circle.dance.animate(duration: 2.0.dampingRatio: 0.5) {
    $0.center = newCenter
}Copy the code

Adding Completion Blocks

Add as many completion blocks as you need, wherever you need to. When an animation finishes, either by playing out the set animation or by calling .finish(at:), then all completion blocks are triggered.

circle.dance.addCompletion { (position) in
    switch position {
    case .start:
        print("Finished the animation at the start position.")
    case .current:
        print("Finished the animation at the current position.")
    case .end:
        print("Finished the animation at the end position.")}}Copy the code

Note: you can’t add a completion block to a finished animation.

Reversing an Animation

Calling this method will reverse the animation in its tracks, like playing a video backwards.

circle.dance.reverse(a)Copy the code

circle.dance.isReversed = trueCopy the code

Note: the position value in the completion block will stay the same after calling .reverse(). For example, if a view’s animation is reversed and the view ends up in its initial position, then the completion closure’s position parameter will be .start, not .end.

Finishing an Animation

Animations will automatically finish when they complete and reach their target values, triggering any completion blocks. However if you pause an animation and/or want to finish that animation early, you must call .finish(at:).

circle.dance.finish(at:.current) // or .start, .endCopy the code

What About Constraints?

Dance works great with constraints. To animate constraint changes:

// update constraints for circle and/or its subviews first
//.
circle.dance.animate(duration: 2.0.curve:.easeInOut) {
    $0.layoutIfNeeded()}Copy the code

Usually most developers would call self.view.layoutIfNeeded() in a standard UIView.animate() block. However this is bad practice as it lays out all subviews in the current view, when they may only want to animate constraint changes for certain views. With Dance, calling $0.layoutIfNeeded() only lays out the view that’s being animated and its subviews, ensuring low energy impact and high FPS.

Debugging

Dance is forgiving, meaning that it handles any mistakes that you might make without causing any runtime errors. If you do make a mistake, for example starting an animation that doesn’t exist, then Dance will print the following error in the console:

** Dance Error: view with dance.tag = <tag> does not have an active animation! **
Copy the code

Dance assigns each dance animation a dance tag, which you can access like so:

circle.dance.tagCopy the code

This way you can keep track of you views’ dance animations and easily handle any of Dance’s error print logs.

Furthermore, you can get the state of a view’s dance animation:

switch circle.dance.state {
case .active:
    // A dance animation has been created for the view and has been started.
    // Note: a paused animation's state will return .active
case .inactive:
    // Either there is no dance animation associated with the view, 
    // or an animation exists but hasn't been started.
}Copy the code

Documentation

Option + click on any of Dance’s methods for detailed documentation.

License

Dance uses the MIT license. Please file an issue if you have any questions or if you’d like to share how you’re using Dance.

Questions?

Contact me by email [email protected], or by twitter @sdrzn. Please create an issue if you come across a bug or would like a feature to be added.

Credits

Disco Ball Icon by Effach from the Noun Project