A radical & elegant animation library for iOS.

Overview

Dance

Platform: iOS 10+ Language: Swift 3 CocoaPods compatible License: MIT

InstallationUsageDebuggingAnimatable PropertiesLicense

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 {

    let circle = UIView()

    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
            // ... see 'Animatable Properties' for more options
        }.addCompletion { _ in
            self.view.backgroundColor = .green
        }.start(after: 5.0)
    }
    
    func pauseAnimation() {
        circle.dance.pause()
    }
    
}

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.

Compatibility

Dance requires iOS 10+ and is compatible with Swift 3 projects.

Installation

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

pod 'Dance'

end
  • 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
}

... alternatively:

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

UITimingCurveProvider

let timingParameters = UISpringTimingParameters(mass: 1.0, stiffness: 0.2, damping: 0.5, initialVelocity: CGVector(dx: 0, dy: 5))

circle.dance.animate(duration: 2.0, timingParameters: timingParameters) {
    $0.center = newCenter
}

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
}

bezier curve

https://developer.apple.com/videos/play/wwdc2016/216/

Spring-based Timing Information

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

Starting an Animation

After creating an animation block using .animate { ... }, the animation doesn't start until you call .start().

circle.dance.start()
circle.dance.start(after: 5.0) // for a delay (in seconds) before starting the animation

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.")
    }
}

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

Pausing an Animation

circle.dance.pause()
circle.dance.pause(after: 5.0) // for a delay (in seconds) before pausing the animation

Note: this won't render the view at the paused position, you must then also call .finish(at: .current) to do that.

Reversing an Animation

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

circle.dance.reverse()
circle.dance.isReversed = true

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.

Scrubbing Through an Animation

Dance animations are like movies—you can scrub through them using the .progress property.

circle.dance.setProgress(to: 0.5) // takes value 0-1
circle.dance.progress = 0.5

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, .end

Dance Properties

circle.dance.hasAnimation: Bool { get }
circle.dance.progress: CGFloat { get, set }
circle.dance.isRunning: Bool { get }
circle.dance.isReversed: Bool { get, set }

For debugging purposes:

circle.dance.state: DanceAnimationState { get } // .inactive, .active
circle.dance.tag: Int { get }

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()
}

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.

Function Chaining

Dance allows you to chain multiple animation commands together, resulting in an elegant and easy-to-read syntax. For example:

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 { (position) in
    if position == .end {
        print("Animation reached the target end position!")
    }
}.start(after: 5.0)
circle.dance.pause().setProgress(to: 0.25)
print(circle.dance.pause().progress)
circle.dance.start().reverse()

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! **

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

circle.dance.tag

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.
    // Note: a finished animation is inactive because the animation effectively ceases to exist after it finishes
}

Animatable Properties

UIView Property Changes you can make
frame Modify this property to change the view’s size and position relative to its superview’s coordinate system. (If the transform property does not contain the identity transform, modify the bounds or center properties instead.)
bounds Modify this property to change the view’s size.
center Modify this property to change the view’s position relative to its superview’s coordinate system.
transform Modify this property to scale, rotate, or translate the view relative to its center point. Transformations using this property are always performed in 2D space. (To perform 3D transformations, you must animate the view’s layer object using Core Animation.)
alpha Modify this property to gradually change the transparency of the view.
backgroundColor Modify this property to change the view’s background color.
contentStretch Modify this property to change the way the view’s contents are stretched to fill the available space.

https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html

Documentation

Option + click on any of Dance's methods for detailed documentation. 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.

Contribute

Dance is in its infancy, but v1.0 provides the barebones of a revolutionary new way to animate in iOS. Please feel free to send pull requests of any features you think would add to Dance and its philosophy.

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

You might also like...
Animation library for iOS in Swift
Animation library for iOS in Swift

TweenKit TweenKit is a powerful animation library that allows you to animate (or 'tween') anything. TweenKit's animations are also scrubbable, perfect

This library is for adding animation to iOS tabbar items, which is inherited from UITabBarController.
This library is for adding animation to iOS tabbar items, which is inherited from UITabBarController.

This library is for adding animation to iOS tabbar items, which is inherited from UITabBarController. Installation Just add the Sources folder to your

A fantastic Physical animation library for swift
A fantastic Physical animation library for swift

A fantastic Physical animation library for swift(Not Just Spring !!!), it is base on UIDynamic and extension to it, friendly APIs make you use it or c

An Objective-C animation library used to create floating image views.
An Objective-C animation library used to create floating image views.

JRMFloatingAnimation [![CI Status](http://img.shields.io/travis/Caroline Harrison/JRMFloatingAnimation.svg?style=flat)](https://travis-ci.org/Caroline

Anima is chainable Layer-Based Animation library for Swift5.
Anima is chainable Layer-Based Animation library for Swift5.

Anima Anima is chainable Layer-Based Animation library for Swift5. It support to make sequensial and grouped animation more easily. is written as foll

Lightweight animation library for UIKit
Lightweight animation library for UIKit

MotionAnimation Lightweight animation library for UIKit in Swift Checkout the Examples folder for more. Consider MotionAnimation as a extremely simpli

☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting
☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting

Features • Guides • Installation • Usage • Miscellaneous • Contributing 🌎 README is available in other languages: 🇪🇸 . 🇨🇳 . 🇧🇷 . 🇰🇷 . 🇫🇷 To

☠️SkeletonUI aims to bring an elegant, declarative syntax to skeleton loading animations.
☠️SkeletonUI aims to bring an elegant, declarative syntax to skeleton loading animations.

SkeletonUI aims to bring an elegant, declarative syntax to skeleton loading animations. Get rid of loading screens or spinners and start using skeletons to represent final content shapes.

A DSL to make animation easy on iOS with Swift.
A DSL to make animation easy on iOS with Swift.

This project is highly inspired by JHChainableAnimations, If you project is developed with Objective-C, use JHChainableAnimations instead. With DKChai

Comments
  • No such module 'Dance'

    No such module 'Dance'

    I tried the approach of dragging and dropping Dance.swift into my project and saw the error that No such module 'Dance'.

    I then tried the Cocoapods approach and see that Dance is installed but still get the same error.

    The sample project included with Dance works but I seem to be unable to use this in another project. I tried cleaning and cleaning the build folder to no avail.

    Any suggestions or can you include a demo video?

    pod update
    Update all pods
    Updating local specs repositories
    Analyzing dependencies
    Downloading dependencies
    Using Dance (1.0.6)
    Generating Pods project
    Integrating client project
    Sending stats
    Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
    

    PS. In the DanceExample, I dont see an import Dance but only the import UIKit

    opened by eapen 2
  • Removed public protocol CGFloatConvertible

    Removed public protocol CGFloatConvertible

    Changed setProgress(to:) to use ExpressibleByFloatLiteral

    The reasoning behind this pull request is to stop the library from exposing the CGFloatConvertible protocol to the user's code, as it is not necessary for the setProgress(to:) function to be able to accept the types: Float, Double and CGFloat.

    opened by TwoLivesLeft 1
Releases(v1.0.7)
Owner
Saoud Rizwan
Full Stack & Mobile Engineer
Saoud Rizwan
SwiftUI-Text-Animation-Library - Text animation library for SwiftUI

⚠️ This repository is under construction. SwiftUI Text Animation Library Make yo

null 28 Jan 8, 2023
A powerful, elegant, and modular animation library for Swift.

MotionMachine provides a modular, powerful, and generic platform for manipulating values, whether that be animating UI elements or interpolating prope

Brett Walker 387 Dec 9, 2022
Elegant SVG animation kit for swift

Elephant This is SVG animation presentation kit for iOS. Example You can run example app. Please open Example-iOS/Elephant-iOS.xcworkspace! Usage You

Kazumasa Shimomura 127 Dec 14, 2022
Simple Interface Core Animation. Run type-safe animation sequencially or parallelly

Simple Interface Core Animation Sica can execute various animations sequentially or parallelly. Features Animation with duration and delay parallel /

CATS Open Source Softwares 1k Nov 10, 2022
An experiment for using SwiftUI's custom timing Animation to create an orbital-like animation.

Orbital-SwiftUI-Animation An experiment for using SwiftUI's custom timing curve to create an orbital-like animation. How it looks: How it works: Apply

Mostafa Abdellateef 7 Jan 2, 2023
Swiftui-animation-observer - Track SwiftUI animation progress and completion via callbacks

SwiftUI Animation Observer Track SwiftUI animation progress and completion via c

Gordan Glavaš 9 Nov 5, 2022
An elegant and flexible tweening library for iOS and tvOS.

PMTween is an elegant and flexible tweening library for Objective-C, currently supporting the iOS and tvOS platforms. It offers sensible default funct

Brett Walker 349 Nov 25, 2022
Easy animation library on iOS with Swift2

Cheetah Cheetah is an animation utility on iOS with Swift. Cheetah can animate any properties since Cheetah uses simple CADisplayLink run loop to chan

Suguru Namura 592 Dec 6, 2022
An extensible iOS and OS X animation library, useful for physics-based interactions.

Pop is an extensible animation engine for iOS, tvOS, and OS X. In addition to basic static animations, it supports spring and decay dynamic animations

Meta Archive 19.8k Dec 28, 2022
Swift animation library for iOS, tvOS and macOS.

anim is an animation library written in Swift with a simple, declarative API in mind. // moves box to 100,100 with default settings anim { self.bo

Onur Ersel 555 Dec 12, 2022