Coder Social home page Coder Social logo

swiftyanimate's Introduction

SwiftyAnimate

Composable animations in Swift. Blog

Platform: iOS 8+ Language: Swift 3

Cocoapods compatible Carthage compatible SPM compatible

Docs Codecov Travis

License: MIT

Installation

Cocoapods

The easiest way to get started is to use CocoaPods. Just add the following line to your Podfile:

pod 'SwiftyAnimate', '~> 1.0.1'

Carthage

github "rchatham/SwiftyAnimate"

Swift Package Manager

Add the following line

.Package(url: "https://github.com/rchatham/SwiftyAnimate.git", majorVersion: 0) 

to your Package.swift file as illustrated below.

import PackageDescription

let package = Package(
    name: "YourAppName",
    targets: [],
    dependencies: [
        .Package(url: "https://github.com/rchatham/SwiftyAnimate.git", majorVersion: 0),
    ]
)

This!

// Escape the Pyramid of DOOM!
Animate(duration: time) { [unowned self] in
    // animation
    self.animationFunction()
}.do { [unowned self] in
    // non-animation function
    self.nonAnimationFunction()
}.then(duration: time) { [unowned self] in
    // animation
    self.animationFunction()
}.wait { [unowned self] resume in
    // function that takes time
    self.functionThatTakesTime {
        resume()
    }
}.then(duration: time) { [unowned self] in
    // animation
    self.animationFunction()
}.then(duration: time) { [unowned self] in
    // animation
    self.animationFunction()
}.perform()

Not this!

// Or... the Pyramid of DOOM!!!!
UIView.animate(withDuration: time, animations: { [unowned self] in
    // animation
    self.animationFunction()
}) {  [unowned self] success in
    // non-animation function
    self.nonAnimationFunction()
    UIView.animate(withDuration: time, animations: {
        // animation
        self.animationFunction()
    }) { success in
        // function that takes time
        self.functionThatTakesTime {
            UIView.animate(withDuration: time, animations: {
                // animation
                self.animationFunction()
            }) { success in
                UIView.animate(withDuration: time, animations: {
                    // animation
                    self.animationFunction()
                })
            }
        }
    }
}

Usage

This library can be used to design simple to complex animations and keeps animation code readable and maintainable.

Composing Animations

Compose animations and insert logic to the flow of animations using the then, do, and wait functions.

Then blocks

Add animations to the current instance using one of the implementations for this function. There are implemetations for both standard and spring animations as well as chaining animation instances.

Animate(duration: 1.0) {
        // animation code goes here
    }
    .then(duration: 0.5) {
        // more animation code
    }
    .perform()

Do blocks

Add code that you don't intend on animating but would like to perform between animations here. Any code you put here will NOT be animated.

Animate(duration: 1.0) {
        // animation code goes here
    }
    .do {
        // logic you don't want to animate
    }
    .then(duration: 0.5) {
        // more animation code
    }
    .perform()

Wait blocks

Add code that you may want to pause an ongoing chain of animations for. Any code you put here will NOT be animated. You can pass in a timeout if you want to wait for a specific amount of time or if you don't want to wait longer to execute the code in the wait block.

Animate(duration: 1.0) {
        // animation code goes here
    }
    .wait(timeout: 5.0) { resume in
        // logic you don't want to pause an animation to complete
        resume()
    }
    .then(duration: 0.5) {
        // more animation code
    }
    .perform()

Performing Animations

There are two ways to perform animations finish and perform. Important: You must either call one of these two functions or decay on an animation instance or this will result in a memory leak!

Perform

This one is easy. Call this on an animation instance to perform it. Perform takes an optional closure which gets excecuted on completing the last animation block.

let animation = Animate(duration: 1.0) {
    // animations
}

animation.perform()

Finish

If you don't need to pass in a completion closure try calling finish on your animation instance. The animation passed in is enqueue'd and then perform is called on the instance. Finish has all of the same variations as the then function.

Animate(duration: 1.0) {
        // animations
    }
    .finish(duration: 1.0) {
        // animations
    }

Decay

If you would like to deallocate an animation instance without performing it call decay on it.

let animation = Animate(duration: 1.0) {
    // animations
}

animation.decay()

Best Practices

The best way to take advantage of this library is define extensions for the views that you would like to animate. This compartmentailizes your code and keep all the animation logic tucked up within the view and out of your view controllers.

extension AnimatingView {
    func bounceAnimation() -> Animate {
        return Animate(duration: 0.3) { [unowned self] in
            self.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        }
        .then(duration: 0.3) { [unowned self] in
            self.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        }
        .then(duration: 0.3) { [unowned self] in
            self.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
        }
        .then(duration: 0.3) { [unowned self] in
            self.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
        }
    }
}

Then when you go to perform an animation you just have to call perform() on the returned animation.

let animatingView = AnimatingView()

animatingView.bounceAnimation().perform()

And string them together with other animations for building up complex animation logic easily.

Animate()
    .then(animation: animatingView.bounceAnimation())
    .then(animation: animatingView.tiltAnimation())
    .then(animation: animatingView.bounceAnimation())
    .perform()

Contributing

I would love to see your ideas for improving this library! The best way to contribute is by submitting a pull request. I'll do my best to respond to your patch as soon as possible. You can also submit a new GitHub issue if you find bugs or have questions. ๐Ÿ™

Please make sure to follow our general coding style and add test coverage for new features!

swiftyanimate's People

Contributors

rchatham avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.