A powerful, elegant, and modular animation library for Swift.

Overview

MotionMachine logo

swift platforms license

MotionMachine provides a modular, powerful, and generic platform for manipulating values, whether that be animating UI elements or interpolating property values in your own classes. It offers sensible default functionality that abstracts most of the hard work away, allowing you to focus on your work. While it is type-agnostic, MotionMachine does support most major UIKit types out of the box and provides syntactic sugar to easily manipulate them. But it's also easy to dive in and modify for your own needs, whether that be custom motion classes, supporting custom value types, or new easing equations.

  • Animation engine built from the ground up (not tied to Core Animation).
  • Motions can be grouped, sequenced, and nested in any arrangement and have reversing and repeating actions applied at any level.
  • Animate properties of UIKit or any generic classes.
  • Includes both static and physics-based motion classes, and both support additive animation.
  • Powerfully modular – most aspects can be customized or outright replaced to fit your specific needs.
  • Provides status callback closures for many types of motion events.
  • Fully tested
  • Fully documented

Getting Started

Get started with the Motion Classes guide for detailed explanations and examples.

Also check out the Examples project to see all the MotionMachine classes in action, or dive deep into the source Documentation.

Introduction

MotionGroup animation

This complex animation was created with the code sample below. These Motion classes animate the NSLayoutConstraints of the circle views (the constraints object in the target parameter is a dictionary of NSLayoutConstraint references) as well as one of their backgroundColor properties. A MotionGroup object is used to synchronize the four Motion objects and reverse their movements.

let group = MotionGroup()

.add(Motion(target: constraints["circleX"]!,
        properties: [PropertyData("constant", 200.0)],
          duration: 1.0,
            easing: EasingQuartic.easeInOut()))

.add(Motion(target: constraints["circleY"]!,
        properties: [PropertyData("constant", 250.0)],
          duration: 1.4,
            easing: EasingElastic.easeInOut()))

.add(Motion(target: circle,
        properties: [PropertyData("backgroundColor.blue", 0.9)],
          duration: 1.2,
            easing: EasingQuartic.easeInOut()))

.add(Motion(target: constraints["circle2X"]!,
        properties: [PropertyData("constant", 300.0)],
          duration: 1.2,
            easing: EasingQuadratic.easeInOut())
            .reverses(withEasing: EasingQuartic.easeInOut()))

.start()

How does this work?

All of the included motion classes in MotionMachine adopt the Moveable protocol, which enables them to work seamlessly together. By using the MotionGroup and MotionSequence collection classes to control multiple motion objects – even nesting multiple layers – you can create complex animations with little effort.

Motion

Motion uses a KVC keyPath (i.e. "frame.origin.x") to target specific properties of an object and transform their values over a period of time via an easing equation. In this example, we pass in PropertyStates structs to the statesForProperties convenience initializer to provide ending value states for the transform and backgroundColor properties of the target object.

let new_color = UIColor.init(red: 91.0/255.0, green:189.0/255.0, blue:231.0/255.0, alpha:1.0)
let circle = circles[0]

motion = Motion(target: circle,
   statesForProperties: [
    PropertyStates(path: "transform", end: circle.transform.scaledBy(x: 1.5, y: 1.5)),
    PropertyStates(path: "backgroundColor", end: new_color)
    ],
              duration: 2.0,
                easing: EasingBack.easeInOut(overshoot: 0.5))
.reverses()
.start()

Motion animation

MotionGroup

MotionGroup is a MoveableCollection class that manages a group of Moveable objects, controlling their movements in parallel. It's handy for controlling and synchronizing multiple Moveable objects. MotionGroup can even control other MoveableCollection objects. In the below example, we told the MotionGroup to reverse and synchronize its child motions while doing so. What this means is that it will pause all motions after the forward movement is done, and only then will it reverse them. In this case, the horizontal movements pause while waiting for the Motion which modifies the second circle's backgroundColor to finish its 3 second duration.

// the MotionGroup will wait for all child motions to finish moving forward before starting their reverse motions
group = MotionGroup().reverses(syncsChildMotions: true)

// move first circle horizontally
let horizontal1 = Motion(target: constraints["x1"]!,
                         properties: [PropertyData("constant", 250.0)],
                         duration: 1.5,
                         easing: EasingSine.easeOut())
.reverses()
group.add(horizontal1)

// reverse and repeat horizontal movement of second circle once, with a subtle overshoot easing
let horizontal2 = Motion(target: constraints["x2"]!,
                  properties: [PropertyData("constant", 250.0)],
                  duration: 1.0,
                  easing: EasingBack.easeOut(overshoot: 0.12))
.reverses()
group.add(horizontal2)

// change backgroundColor of second circle
let color = Motion(target: circles[1],
                   statesForProperties: [PropertyStates(path: "backgroundColor", end: UIColor.init(red: 91.0/255.0, green:189.0/255.0, blue:231.0/255.0, alpha:1.0))],
                   duration: 3.0,
                   easing: EasingQuadratic.easeInOut())
group.add(color)

.start()

MotionGroup animation

MotionSequence

MotionSequence is a MoveableCollection class which moves a collection of Moveable objects in sequential order, even other MoveableCollection objects. MotionSequence provides a powerful and easy way of chaining together value transformations of object properties to do keyframing or to create complex and fluid compound animations of many objects.

// create a reversing MotionSequence with its reversingMode set to contiguous to create a fluid animation from its child motions
sequence = MotionSequence().reverses(.contiguous)

// set up motions for each circle and add them to the MotionSequence
for x in 0..<4 {
    // motion to animate a topAnchor constraint down
    let down = Motion(target: constraints["y\(x)"]!,
                      properties: [PropertyData("constant", 60.0)],
                      duration: 0.4,
                      easing: EasingQuartic.easeInOut())

    // motion to change background color of circle
    let color = Motion(target: circles[x],
                       statesForProperties: [PropertyStates(path: "backgroundColor", end: UIColor.init(red: 91.0/255.0, green:189.0/255.0, blue:231.0/255.0, alpha:1.0))],
                       duration: 0.3,
                       easing: EasingQuadratic.easeInOut())

    // wrap the Motions in a MotionGroup and set it to reverse
    let group = MotionGroup(motions: [down, color]).reverses(syncsChildMotions: true)

    // add group to the MotionSequence
    sequence.add(group)
}
sequence.start()

MotionSequence animation

Installation

MotionMachine supports Swift Packages in Xcode 11 and above.

If you use CocoaPods, add this pod to your Podfile:

Podfile
pod 'MotionMachine', '~> 2.0'

Or add the Sources directory to your project.

Compatibility

MotionMachine currently requires:

  • Swift 5.0
  • Xcode 10.0 or later
  • iOS 8.0 or later, tvOS 9.0 or later

Caveats

  • MotionMachine uses Key-Value Coding (KVC) to introspect objects and retrieve and set their property values using keypaths. Because Swift currently offers no native ability in this regard, objects whose properties should be modified by MotionMachine must inherit from NSObject. If and when more dynamism is added to Swift (and the author of this library hopes that is the case), MotionMachine will hopefully be able to do away with this restriction. Note that as of Swift 4.0, any properties of a custom class you wish to manipulate must be prefixed with @objc, or add @objcMembers above the class if all properties should be exposed.

  • Because native Swift structs cannot inherit from NSObject, Swift structs unfortunately cannot be used directly with MotionMachine at this time, though you can use them in a keyPath if you're not targeting one of their properties directly.

  • The KVC provided by NSObject is not able to evaluate Optional values. Properties you wish to modify with MotionMachine must not be Optionals.

  • Swift on Linux is not currently supported due to the lack of Foundation and Core Graphics frameworks on that platform.

Credits

MotionMachine was created by Brett Walker. It is loosely based on the author's Objective-C library PMTween.

License

MotionMachine is licensed under the MIT License. See LICENSE for details.

I'd love to know if you use MotionMachine in your projects!

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

☠️ 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

Easy animation library on iOS with Swift2
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

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

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

☠️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.

Simple and powerful animated progress bar with dots

Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 8.0+ Swift 3.0+ Installatio

Comments
  • Animating via constraint toggle?

    Animating via constraint toggle?

    Currently, with UIView.animate, it is possible to do an animation through a constraint toggle. For example, if we have an object rect, and we have two layout constraints on its location, constrainRectToTop and constrainRectToTop, we can do as follows:

    UIView.animate(withDuration: 0.35, delay: 0.35, animations: {
                        self.constrainRectToTop.isActive = false
                        self.constrainRectToBottom.isActive = true
                        self.view.layoutIfNeeded()
                    }
    

    What would be a general way of accomplishing this using MotionMachine?

    opened by winstondu 0
Releases(2.0.1)
  • 2.0.1(Apr 19, 2021)

  • 2.0.0(Jun 10, 2019)

    • Support for Swift 5.0
    • Updated syntax in MotionOptions for newer Swift naming conventions
    • Updated Swift package file to newest version, requires Xcode 11 to import
    • Bumped version to 2.0.0 due to breaking change in MotionOptions (Swift Package Manager requires packages use semantic versioning)
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Mar 22, 2018)

    • Fixed bugs which prevented some CGStructs from being updated when using Motion’s statesForProperties convenience initializer
    • Added targetsNestedStruct static method to CGStructAssistant, which determines whether a specified keyPath targets a struct of a CGRect
    • Added and improved tests
    • Improved readability and streamlined some code
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Mar 19, 2018)

    • Refactored the "finalState" convenience initializer for the Motion class to now take an Array of PropertyStates objects. This allows you to provide both starting and ending representational value objects for easy animation properties creation. Most of the ValueAssistant objects had significant updates to support this.
    • A new "buildPropertyData(fromObject: AnyObject, propertyStates: [PropertyStates])" public method has been added to the Motion class, which creates and returns an array of PropertyData objects. This method is used in conjunction with the above convenience initializer, but can be called ad hoc to generate PropertyData objects from a set of state objects you pass in.
    • Bugfix: ValueAssistants now won't exclude properties from being created when the ending value is the same as the object's original value, but the specified starting value is different.
    • Minor updates for Swift 4 compatibility. The Examples and Tests projects now target Swift 4.
    • Updated tests, and additional test coverage for ValueAssistant classes.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Sep 22, 2017)

  • 1.1.1(May 23, 2017)

  • 1.1.0(Sep 16, 2016)

Owner
Brett Walker
Brett Walker
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 radical & elegant animation library for iOS.

Installation • Usage • Debugging • Animatable Properties • License Dance is a powerful and straightforward animation framework built upon the new UIVi

Saoud Rizwan 648 Dec 14, 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
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
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
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
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
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
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

August 2.9k Jan 4, 2023