An elegant and flexible tweening library for iOS and tvOS.

Overview

PMTween is an elegant and flexible tweening library for Objective-C, currently supporting the iOS and tvOS platforms. It offers sensible default functionality that abstracts most of the hard work away, allowing you to focus on your animations and other tween tasks. But PMTween also makes it easy to dive in and modify for your own needs, whether that be custom tweening classes, supporting custom object types, or new easing equations.

If you're coding in Swift, try MotionMachine, which is based on PMTween, but with many improvements and an API tailored to that langauge.

Overview

  • PMTween makes both simple and complex tweening tasks easy to create.
  • Tweens can be grouped, sequenced, and nested in most any configuration you might need.
  • Includes both static and physics-based tween classes.
  • PMTween was built to easily support custom value types, easing equations, and functionality.
  • Provides notifications and blocks for many kinds of status events.

All of the base tweening classes in PMTween adopt the PMTweening protocol, and you can add any of these classes to a PMTweenGroup or PMTweenSequence instance. They can be nested as many levels deep as you'd like, and PMTweenGroup and PMTweenSequence respect the tweening properties of their children. If you want to use your own custom tween classes, simply adopt the protocol. However, PMTweenUnit offers such modularity that in most cases you can just replace the parts you need with your own implementation.

In other words, this code:

PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenEasingBlock easing2 = [PMTweenEasingCircular easingInOut];

PMTweenUnit *tween1 = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.origin.x" startingValue:self.tweenView.frame.origin.x endingValue:110 duration:1.5 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween2 = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"backgroundColor.blue" startingValue:0.30 endingValue:1.0 duration:1.2 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween3 = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.size.width" startingValue:self.tweenView.frame.size.width endingValue:120 duration:0.9 options:PMTweenOptionNone easingBlock:easing2];
PMTweenUnit *tween4 = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.origin.y" startingValue:self.tweenView.frame.origin.y endingValue:100 duration:1.0 options:PMTweenOptionNone easingBlock:easing];

PMTweenGroup *group = [[PMTweenGroup alloc] initWithTweens:@[tween1, tween2] options:PMTweenOptionNone];

PMTweenSequence *sequence = [[PMTweenSequence alloc] initWithSequenceSteps:@[group, tween3, tween4] options:PMTweenOptionReverse|PMTweenOptionRepeat];
sequence.reversingMode = PMTweenSequenceReversingContiguous;
[sequence startTween];

produces this animation:

sequence

New in 1.2.0

New in the 1.2.0 release is support for additive animations in PMTweenUnit. Additive animation allows multiple tweens to produce a compound effect, instead of overwriting each other as they update the same property. Additive animation is now the default behavior for tweening animations in iOS 8, and is great for making user interface animations fluid and responsive. Of course with PMTweenUnit you are not limited to tweening UIView properties, so additive tweening may be applied to any compatible property. Simply set additive to YES on any PMTweenUnit instances whose tweening updates you wish to composite. Please see the documentation and updated Examples project for more information and things you should keep in mind when using this mode. Special thanks to Andy Matuschak and Kevin Doughty for making the concept clearer.

additive

New in 1.1.0

New in the 1.1.0 release is PMTweenPhysicsUnit, which provides dynamic, physics-based tweening. (Thanks to Pop lib for the inspiration!) Since it adopts the PMTweening protocol, you can combine it with the other PMTween classes as you see fit.

For more information, see the included examples of PMTween usage, and peruse the documentation.

Getting Started

Installation

If you use CocoaPods:

Podfile
pod "PMTween", "~> 1.3.0"

Or add the Classes directory to your project.

Examples

Basic tween

Here's the most basic type of tween, which just tweens an arbitrary data structure directly. PMTweenUnit is the workhorse tweening class in PMTween; it handles all the actual property updating. Note that nil is passed in for the easingBlock, which means it will use the default PMTweenEasingLinear easing type.

#import <PMTween/PMTween.h>

PMTweenUnit *tween = [[PMTweenUnit alloc] initWithProperty:@(0) startingValue:0 endingValue:100 duration:1.0 options:PMTweenOptionNone easingBlock:nil];
[tween startTween];

Here's another basic example. Notice that this time we've passed an options bitmask into the options parameter which will make it tween in reverse back to the starting value (after hitting the endingValue), and also repeat its tween for multiple cycles. In this case, it would repeat the total tween operation (forwards and back).

We've also defined a completeBlock, which will be called when the tween has completed all repeat cycles. Notice that the block's parameter specifies NSObject<PMTweening>, and not PMTweenUnit. It denotes that this could be any object that conforms to the PMTweening protocol. If you want to access specific properties from your tweening class that are not specified by the PMTweening protocol, you will need to cast the 'tween' object to your specific class type first.

PMTweenUnit *tween = [[PMTweenUnit alloc] initWithProperty:@(0) startingValue:0 endingValue:100 duration:1.0 options:PMTweenOptionRepeat|PMTweenOptionReverse easingBlock:nil];
tween.completeBlock = ^void(NSObject<PMTweening> *tween) {
    NSLog(@"tween complete!");
};
tween.numberOfRepeats = 2;
[tween startTween];

Tweening an object's property

A more common need is to tween an object property, such as the x position of a UIView. Check the example below. Notice that this method requires a key path. This is the object hierarchy from the object down to the property you want to tween. Even though the 'x' value can't be set directly on a frame's origin, PMTween is smart enough to handle this updating for you. PMTween handles most common UIKit properties; see the docs or the code for exactly what it supports, and let me know what it's missing.

Notice also that we've defined an easingBlock this time. You can also assign a different easing block to use when reversing a tween by setting a PMTweenUnit's reverseEasingBlock property. PMTween includes all the standard Robert Penner easing types, but you can also easily use your own easing classes. Maybe you want to modify the easing by applying a Perlin noise filter or shifting the value with gyroscope data. Who knows? I don't. That's why PMTween makes it easy for you to do your own thing.

PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.origin.x" startingValue:self.tweenView.frame.origin.x endingValue:200 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
[tween startTween];

Using a PMTweenGroup

PMTweenGroup manages multiple class instances. It's handy for controlling and synchronizing multiple tween objects. You can of course have groups within other groups.

Notice in this example that a tempo object is being set on the PMTweenGroup. It provides a tempo, or in other words a rate at which the tween should update its easing calculations. This is not necessary to set unless you want to use your own custom tempo object – all PMTween tweening classes by default create their own tempo objects internally.

PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.size.width" startingValue:self.tweenView.frame.size.width endingValue:200 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween2 = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.size.height" startingValue:self.tweenView.frame.size.height endingValue:300 duration:2.0 options:PMTweenOptionNone easingBlock:easing];

PMTweenGroup *group = [[PMTweenGroup alloc] initWithTweens:@[tween, tween2] options:PMTweenOptionReverse];
[group setTempo:[PMTweenCATempo tempo]];
[group startTween];

Using a PMTweenSequence

PMTweenSequence plays a collection of tweens in order. Chaining tweens together is extremely easy. This is a powerful class, as you can play in sequence any assortment of PMTweenUnits, PMTweenGroups, or other PMTweenSequence classes, as well as your own custom tween classes. It's tweens all the way down. Note that we pass in an array of sequence steps – it will play the sequence in that order.

When a PMTweenSequence is set to reverse, by default it will play as discrete elements when reversing (in other words, each child tween would just play forwards, but in reverse order). But by setting the sequence's reversingMode to PMTweenSequenceReversingContiguous you can set the whole sequence to play in reverse seamlessly, as if it was one contiguous tween. This is really great for complex animations.

PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.origin.x" startingValue:self.tweenView.frame.origin.x endingValue:200 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween2 = [[PMTweenUnit alloc] initWithObject:self.tweenView  propertyKeyPath:@"frame.size.height" startingValue:self.tweenView.frame.size.height endingValue:300 duration:2.0 options:PMTweenOptionNone easingBlock:easing];

PMTweenSequence *sequence = [[PMTweenSequence alloc] initWithSequenceSteps:@[tween1, tween2] options:PMTweenOptionReverse];
[sequence startTween];

Class reference

Tween Classes
PMTweenUnit PMTweenUnit handles a single tween operation on an NSValue, interpolating between specified starting and ending values.
PMTweenPhysicsUnit PMTweenPhysicsUnit handles a single physics-based tween operation on an NSValue, using a physics system to update a value with decaying velocity.
PMTweenGroup PMTweenGroup handles the tweening of one or more objects which conform to the PMTweening protocol, either being instances of PMTweenUnit or other custom classes. The PMTweenGroup class is a good solution when you want to easily synchronize the operation of many tweens.
PMTweenSequence PMTweenSequence allows objects which conform to the PMTweening protocol to be chained together in a sequential series of tween steps.
Tempo Classes
PMTweenCATempo PMTweenCATempo is a concrete subclass of PMTweenTempo, and uses a CADisplayLink object to send out tempo updates that are synchronized with the refresh rate of the display.
PMTweenBeat PMTweenBeat broadcasts updates from a PMTweenTempo object to multiple objects which adopt the PMTweening protocol. This allows you to use a single tempo object for all tween objects, avoiding a performance impact when tweening many objects.
Easing Types
PMTweenEasingLinear Provides a linear easing equation.
PMTweenEasingQuadratic Provides quadratic easing equations.
PMTweenEasingQuartic Provides quartic easing equations.
PMTweenEasingQuintic Provides quintic easing equations.
PMTweenEasingCubic Provides cubic easing equations.
PMTweenEasingSine Provides easing equations based on sine.
PMTweenEasingCircular Provides circular easing equations.
PMTweenEasingElastic Provides easing equations that behave in an elastic fashion.
PMTweenEasingExpo Provides exponential easing equations.
PMTweenEasingBack Provides back easing equations.
PMTweenEasingBounce Provides easing equations that have successively smaller value peaks, like a bouncing ball.

Tests

PMTween is tested using Specta/Expecta. You can install the test dependencies using CocoaPods by running 'pod install' from within the Tests directory.

Credits

PMTween was created by Brett Walker of Poet & Mountain.

Compatibility

  • Requires iOS 7.0 or later, tvOS 9.0 or later
  • PMTween uses ARC

License

PMTween is licensed under the MIT License. I'd love to know if you use PMTween in your app!

You might also like...
This repo contains swift collection of gui, games, menu, animations, music, payment, etc... for iOS, macOS, watchOS and tvOS
This repo contains swift collection of gui, games, menu, animations, music, payment, etc... for iOS, macOS, watchOS and tvOS

Swift-Collections About: This repo contains a collection of projects built using swift and objective-c Contains projects for macOS iOS iPad watchOS tv

SwiftUI Animation Library. Useful SwiftUI animations including Loading/progress, Looping, On-off, Enter, Exit, Fade, Spin and Background animations that you can directly implement in your next iOS application or project. The library also contains huge examples of spring animations such as Inertial Bounce, Shake, Twirl, Jelly, Jiggle, Rubber Band, Kitchen Sink and Wobble effects. Browse, find and download the animation that fits your needs.
This library for animating text. Developed with SwiftUI. This library supports iOS/macOS.

AnimateText This library for animating text. Developed with SwiftUI. This library supports iOS/macOS. Screenshot AnimateText.mp4 Example https://fabul

SwiftUI-Text-Animation-Library - Text animation library for SwiftUI
SwiftUI-Text-Animation-Library - Text animation library for SwiftUI

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

(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey 🍯 to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey 🍯 to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

An extensible iOS and OS X animation library, useful for physics-based interactions.
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

A library of custom iOS View Controller Animations and Interactions.
A library of custom iOS View Controller Animations and Interactions.

RZTransitions is a library to help make iOS7 custom View Controller transitions slick and simple. Installation CocoaPods (Recommended) Add the followi

LottieUI - A library developed to make Lottie easy to implement. It supports iOS and macOS

LottieUI It is a library developed to make Lottie easy to implement. It supports

Comments
  • Can you handle custom properties?

    Can you handle custom properties?

    I am very interested by your library. I am currently using CoconutKit but i am looking at switching library. I want something more in the lines of Android animation system which i find stronger.

    I have 2 questions about your library:

    • can you handle custom properties? Let s say i have a custom layer drawing an arc, and i want to animated the arc sweep angle.
    • Would it be possible to have a tween with an UIView animation block? That way we could still do easy UIview animations.

    Thanks

    opened by farfromrefug 3
  • abs -> fabs

    abs -> fabs

    Because warnings suck.

    Also by the way Examples/PMTweenExamples/Classes/AdditiveVC.m gives a static analyser warning because a line of code is never used, why is it there anyways 😛

    opened by Schemetrical 1
Releases(1.3.3)
  • 1.3.3(Mar 2, 2016)

    • PMTweenPhysicsSystem (used internally by PMTweenPhysicsUnit) now uses a fixed timestep, which though rudimentary, helps smooth out tween value jittering
    • Fixed bug with physics timer not properly removed
    Source code(tar.gz)
    Source code(zip)
  • 1.3.2(Feb 29, 2016)

    • PMTweenPhysicsUnit now updates its physics system independently of property updates, at a frequency of 120 fps by default (to provide double the resolution of a normal 60fps app). This can be changed by PMTweenPhysicsUnit's new property physicsTimerInterval.
    • PMTweenPhysicsSystem now handles friction values with less accumulated error.
    • PMTweenPhysicsUnit's velocity is now expressed in units per second. Prior to this the velocity acted as units per frame, which obviously caused inconsistent simulations.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Jan 26, 2016)

    • Updated project architecture to use single header import
    • Fixed string equality check in PMTweenSupport when comparing keyPaths
    • Miscellaneous project cleanup
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Jan 15, 2016)

    • Added support for CGVector structs as property tweening targets.
    • Added support for tvOS as a target.
    • Updated init methods to use instancetype
    • Changed minimum iOS target to 7.0.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jul 12, 2014)

    • Implemented additive animation in PMTweenUnit! • Updated PMTweenObjectUpdater to provide additive updating support. • Updated tests. • Updated Examples project to include additive demos.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.2(Jun 3, 2014)

  • 1.1.1(Jun 3, 2014)

    • Fixed PMTweenUnit and PMTweenPhysicsUnit failing to tween object properties specified by a single-element keyPath. • Fixed NSNumber object properties with a nil value not tweening. Such properties are now initialized with the specified starting value during the init method. • Changed all init methods to return instancetype instead of id. • More tests.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(May 6, 2014)

    • Added PMTweenPhysicsUnit and PMTweenPhysicsSystem classes to provide dynamic, physics-based tweening! PMTweenPhysicsUnit adopts PMTweening, so you get all the standard PMTween functionality – use it in groups and sequences, add reversing, pause it, etc. See the documentation and examples project for more info.
    • Fixed bug where PMTweening classes set to reversing wouldn't reverse properly inside a PMTweenGroup that wasn't itself reversing.
    • currentValue property wasn't being set to startingValue in PMTweenUnit on setup.
    • New tests.
    • Updated examples project.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Apr 27, 2014)

    • PMTweenBeat: Fixed this class not having a default tempo or setting child tween tempos to nil.
    • PMTweenGroup: Base init method was not calling setTempo.
    Source code(tar.gz)
    Source code(zip)
Owner
Brett Walker
Brett Walker
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
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
TRightImageButton is a simple and flexible UI component fully written in Swift.

TRightImageButton is a simple and flexible UI component fully written in Swift. TRightImageButton is developed to help programmers create a button with right image quickly without having to write many lines of codes.

Nguyen Duc Thinh 2 Aug 18, 2022
TTouchAnimatedButton is a simple and flexible animation component fully written in Swift

TTouchAnimatedButton is a simple and flexible animation component fully written in Swift. TTouchAnimatedButton is developed to make user feel button click becomes more vivid and realistic.

Nguyen Duc Thinh 2 Aug 18, 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 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

Juanpe Catalán 11.7k Jan 3, 2023
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
☠️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.

Carlos Solana Martínez 551 Dec 18, 2022
Physics-based animations for iOS, tvOS, and macOS.

Advance An animation library for iOS, tvOS, and macOS that uses physics-based animations (including springs) to power interactions that move and respo

Tim Donnelly 4.5k Dec 29, 2022
Twinkle is a Swift and easy way to make any UIView in your iOS or tvOS app twinkle.

Twinkle ✨ Twinkle is a Swift and easy way to make any UIView in your iOS or tvOS app twinkle. This library creates several CAEmitterLayers and animate

patrick piemonte 600 Nov 24, 2022