{"id":15037753,"url":"https://github.com/rchatham/swiftyanimate","last_synced_at":"2025-04-09T23:32:26.922Z","repository":{"id":62456845,"uuid":"71315381","full_name":"rchatham/SwiftyAnimate","owner":"rchatham","description":"Composable animations in Swift","archived":false,"fork":false,"pushed_at":"2017-10-02T01:59:49.000Z","size":363,"stargazers_count":195,"open_issues_count":4,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-20T23:16:45.276Z","etag":null,"topics":["animation","animations","carthage","cocoapods","composable-animations","ios","swift","swift-3","tested"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rchatham.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-19T03:29:07.000Z","updated_at":"2025-01-06T15:48:59.000Z","dependencies_parsed_at":"2022-11-01T23:46:30.993Z","dependency_job_id":null,"html_url":"https://github.com/rchatham/SwiftyAnimate","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchatham%2FSwiftyAnimate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchatham%2FSwiftyAnimate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchatham%2FSwiftyAnimate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rchatham%2FSwiftyAnimate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rchatham","download_url":"https://codeload.github.com/rchatham/SwiftyAnimate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248129947,"owners_count":21052668,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","animations","carthage","cocoapods","composable-animations","ios","swift","swift-3","tested"],"created_at":"2024-09-24T20:35:32.666Z","updated_at":"2025-04-09T23:32:26.896Z","avatar_url":"https://github.com/rchatham.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"http://reidchatham.com/src/SwiftyAnimate.png\"\u003e\n\n### Composable animations in Swift. [Blog](https://goo.gl/EHT54H)\n\n![Platform: iOS 8+](https://img.shields.io/badge/platform-iOS%208%2B-blue.svg?style=flat)\n[![Language: Swift 3](https://img.shields.io/badge/language-swift3-f48041.svg?style=flat)](https://developer.apple.com/swift)\n![License: MIT](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)\n\n[![Cocoapods compatible](https://cocoapod-badges.herokuapp.com/v/SwiftyAnimate/badge.png)](https://cocoapods.org/pods/SwiftyAnimate)\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![SPM compatible](https://img.shields.io/badge/spm-supported-orange.svg)](https://swift.org/package-manager/)\n\n[![Docs](https://img.shields.io/cocoapods/metrics/doc-percent/SwiftyAnimate.svg)](http://cocoadocs.org/docsets/SwiftyAnimate)\n[![Codecov](https://img.shields.io/codecov/c/github/rchatham/SwiftyAnimate.svg)](https://codecov.io/gh/rchatham/SwiftyAnimate)\n[![Travis](https://img.shields.io/travis/rchatham/SwiftyAnimate.svg)](https://travis-ci.org/rchatham/SwiftyAnimate)\n[![Code Climate](https://codeclimate.com/github/rchatham/SwiftyAnimate/badges/gpa.svg)](https://codeclimate.com/github/rchatham/SwiftyAnimate)\n\n\u003cimg src=\"http://reidchatham.com/src/SwiftyAnimate.gif\" width=\"200\"\u003e\n\n\n## Installation\n\n#### Cocoapods\n\nThe easiest way to get started is to use [CocoaPods](http://cocoapods.org/). Just add the following line to your Podfile:\n\n```ruby\npod 'SwiftyAnimate', '~\u003e 1.3.0'\n```\n\n#### Carthage\n\n```ruby\ngithub \"rchatham/SwiftyAnimate\"\n```\n\n#### Swift Package Manager\n\nAdd the following line to your Package.swift file. \n\n```swift\n.Package(url: \"https://github.com/rchatham/SwiftyAnimate.git\", majorVersion: 0) \n```\n\n## Usage\n\nThis library can be used to design composable animations while keeping animation code readable and maintainable.\n\n### Composing Animations\n\nCompose animations and insert logic inbetween them using the `then`, `do`, and `wait` functions.\n\n#### Then blocks\n\nAdd animations to the current instance using one of the implementations for this function. There are implemetations for spring and keyframe animations as well as chaining `Animate` objects together.\n\n```swift\nAnimate(duration: 1.0) {\n        // animation code goes here\n    }\n    .then(duration: 0.5) {\n        // more animation code\n    }\n    .perform()\n```\n\n#### And blocks\n\nAdd animations to the current instance using one of the implementations for this function. There are implemetations for spring and keyframe animations as well as stacking `Animate` objects together. 'And' animations are performed in sync with the animation before it.\n\n```swift\nAnimate(duration: 1.0) {\n        // animation code goes here\n    }\n    .and(duration: 0.5) {\n        // more animation code\n    }\n    .perform()\n```\n\n#### Do blocks\n\nAdd 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.\n\n```swift\nAnimate(duration: 1.0) {\n        // animation code goes here\n    }\n    .do {\n        // logic you don't want to animate\n    }\n    .then(duration: 0.5) {\n        // more animation code\n    }\n    .perform()\n```\n\n#### Wait blocks\n\nAdd 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. \n\n```swift\nAnimate(duration: 1.0) {\n        // animation code goes here\n    }\n    .wait(timeout: 5.0) { resume in\n        // logic you want to pause an animation to complete\n        resume()\n    }\n    .then(duration: 0.5) {\n        // more animation code\n    }\n    .perform()\n```\n\n### Performing Animations\n\nThere 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!**\n\n#### Perform\n\nThis 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.\n\n```swift\nlet animation = Animate(duration: 1.0) {\n    // animations\n}\n\nanimation.perform()\n```\n\n#### Finish\n\nIf 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.\n\n```swift\nAnimate(duration: 1.0) {\n        // animations\n    }\n    .finish(duration: 1.0) {\n        // animations\n    }\n```\n\n#### Decay\n\nIf you would like to deallocate an animation instance without performing it call decay on it.\n\n```swift\nlet animation = Animate(duration: 1.0) {\n    // animations\n}\n\nanimation.decay()\n```\n\n### UIView Extensions\n\nA number of animatable properties have extensions defined to make implementing them with this library even easier. Please check the docs!\n\n### Best Practices\n\nThe 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.\n\n```swift\nextension AnimatingView {\n    func bounceAnimation() -\u003e Animate {\n        return Animate()\n            .then(animation: scale(duration: 0.3, x: 1.3, y: 1.3))\n            .then(animation: scale(duration: 0.3, x: 0.8, y: 0.8))\n            .then(animation: scale(duration: 0.3, x: 1.1, y: 1.1))\n            .then(animation: scale(duration: 0.3, x: 1.0, y: 1.0))\n    }\n}\n```\n\nThen when you go to perform an animation you just have to call `perform()` on the returned animation.\n\n```swift\nlet animatingView = AnimatingView()\n\nanimatingView.bounceAnimation().perform()\n```\n\nAnd string them together with other animations for building up complex animation logic easily.\n\n```swift\nAnimate()\n    .then(animation: animatingView.bounceAnimation())\n    .then(animation: animatingView.tiltAnimation())\n    .then(animation: animatingView.bounceAnimation())\n    .perform()\n```\n\n### Contributing\n\nI 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](https://github.com/rchatham/SwiftyAnimate/issues/new) if you find bugs or have questions. 🙏\n\nPlease make sure to follow our general coding style and add test coverage for new features!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frchatham%2Fswiftyanimate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frchatham%2Fswiftyanimate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frchatham%2Fswiftyanimate/lists"}