Animation library for iOS in Swift

Overview

TweenKit

CI Status Version License Platform Twitter

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

tweenkit

Download the example project to see how these animations were created

TweenKit's animations are:

  • Reversible
  • Repeatable
  • Groupable
  • Sequenceable
  • Scrubbable
  • Quick and easy to use!

Example

The example project contains a collection of examples of how to use TweenKit. Run Example.xcodeproj

Installation

TweenKit is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "TweenKit"

Importing TweenKit

Add import TweenKit to the top of the files you want to use TweenKit from

Creating an ActionScheduler

Create an instance of ActionScheduler to run your animations. You should retain the scheduler, so it's best made as a property on your View Controller.

let scheduler = ActionScheduler()

Actions

TweenKit's animations are composed of 'Actions'. These are small animation units that can be chained or grouped to build complex animations. Once you have created an action, you can tell the scheduler to run it.

scheduler.run(action: myAction)

Animating a view's frame

Anything that conforms to the 'Tweenable' protocol, can be animated.

CGRect, CGFloat, Double, Float, UIColor, and other common objects already adopt the 'Tweenable' out of the box.

We can use TweenKit's InterpolationAction to animate a view's frame:

let fromRect = CGRect(x: 50, y: 50, width: 40, height: 40)
let toRect = CGRect(x: 100, y: 100, width: 200, height: 100)
        
let action = InterpolationAction(from: fromRect,
                                 to: toRect,
                                 duration: 1.0,
                                 easing: .exponentialInOut) {
                                    [unowned self] in self.redView.frame = $0
}
        
scheduler.run(action: action)

basictween

Grouping actions

Using an ActionGroup, several animations can be run at once. For instance, we can change a view's frame and it's background color:

// Create a move action
let fromRect = CGRect(x: 50, y: 50, width: 40, height: 40)
let toRect = CGRect(x: 100, y: 100, width: 200, height: 100)
        
let move = InterpolationAction(from: fromRect,
                                 to: toRect,
                                 duration: 2.0,
                                 easing: .elasticOut) {
                        [unowned self] in self.squareView.frame = $0
}
        
// Create a color change action
let changeColor = InterpolationAction(from: UIColor.red,
                                      to: UIColor.orange,
                                      duration: 2.0,
                                      easing: .exponentialOut) {
                        [unowned self] in self.squareView.backgroundColor = $0
}
        
// Make a group to run them at the same time
let moveAndChangeColor = ActionGroup(actions: move, changeColor)
scheduler.run(action: moveAndChangeColor)

grouptween

Running actions in sequence

Using an ActionSequence, several animations can be run in order. This time, we can use supply a closure as the 'from' parameter, to animate the view from it's current frame:

let moveOne = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                                  to: CGRect(x: 120, y: 80, width: 50, height: 50),
                                  duration: 1,
                                  easing: .exponentialInOut) {
                                   [unowned self] in self.squareView.frame = $0
}
        
let moveTwo = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                                  to: CGRect(x: 70, y: 120, width: 130, height: 130),
                                  duration: 1,
                                  easing: .exponentialInOut) {
                                    [unowned self] in self.squareView.frame = $0
}
        
let moveTwice = ActionSequence(actions: moveOne, moveTwo)
scheduler.run(action: moveTwice)

sequencetween

Repeating actions

Use RepeatAction to repeat your actions, or RepeatForeverAction to repeat an action forever. You can easily contruct these using the repeated(times:) and repeatedForever methods on any action:

let repeatedForever = myAction.repeatedForever()
scheduler.run(action: repeatedForever)

Yoyo

If you want your action to go back and forth, you can use a YoyoAction. These can be easily constructed by calling the yoyo() method on any action:

let move = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                               to: CGRect(x: 250, y: 100, width: 100, height: 100),
                               duration: 1,
                               easing: .exponentialInOut) {
                                [unowned self] in self.squareView.frame = $0
}
        
scheduler.run(action: move.yoyo().repeatedForever() )

yoyotween

Arc Actions

ArcAction can animate any object that conforms to Tweenable2DCoordinate in a circular motion.

By creating some ArcActions in a staggared Group, we can easily create an activity indicator:

// Create an ArcAction for each circle layer
let actions = circleLayers.map{
    layer -> ArcAction<CGPoint> in
            
    let action = ArcAction(center: self.view.center,
                           radius: radius,
                           startDegrees: 0,
                           endDegrees: 360,
                           duration: 1.3) {
                            [unowned layer] in layer.center = $0
    }
    action.easing = .sineInOut
    return action
}
        
// Run the actions in a staggered group
let group = ActionGroup(staggered: actions, offset: 0.125)
        
// Repeat forever
let repeatForever = group.repeatedForever()
        
// Run the action
scheduler.run(action: repeatForever)

activityindicator

Bezier Actions

Objects can be animated along a bezier path using BezierAction. The callback supplies both position and rotation.

BezierAction can animate any value that conforms to the Tweenable2DCoordinate protocol.

let action = BezierAction(path: bezierPath, duration: 4.0) {
    [unowned self] (postion, rotation) in
            
    self.rocketImageView.center = postion
            
    let rocketRotation = CGFloat(rotation.value)
    self.rocketImageView.transform = CGAffineTransform(rotationAngle: rocketRotation)
}
    
action.easing = .exponentialInOut
        
scheduler.run(action: action)

rocket

Scrubbable actions

Scrubbable Actions are great for building unique onboarding experiences.

Instead of adding the action to a scheduler, create an ActionScrubber instance:

let move = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                               to: CGRect(x: 130, y: 100, width: 100, height: 100),
                               duration: 1,
                               easing: .elasticOut) {
                                [unowned self] in self.squareView.frame = $0
}
        
self.actionScrubber = ActionScrubber(action: move)

// Scrub the action in a UISlider callback
func sliderChanged(slider: UISlider) {
    actionScrubber.update(t: Double(slider.value))
}

scrubbabletween

Animating your own objects

By adding conformance to the Tweenable protocol, anything can be animated. You decide what it means to 'tween' your object, making this a flexible approach.

For instance, by conforming String to Tweenable we can turn a bat into a cat:

InterpolationAction(from: "bat",
                    to: "cat",
                    duration: 4,
                    easing: .exponentialInOut) {
                     [unowned self] in self.label.text = $0
}

battocat

Other Stuff

Use DelayAction to add a delay in to a sequence

Use CallBlockAction to trigger a callback at any point in a sequence

Author

Steve Barnegren

[email protected]

@stevebarnegren

License

TweenKit is available under the MIT license. See the LICENSE file for more info.

Comments
  • Question: Can this be used to Animate from One image/UIVIew to another?

    Question: Can this be used to Animate from One image/UIVIew to another?

    @SteveBarnegren This library looks super powerful. Based on how you animated the String by having "String" inherit tweenable protocol, I'm wondering if more complex objects such as UIImageViews can be animated?

    opened by otymartin 12
  • enhancement - expose primitive values/variables or document methods to allow hooking into variables changing

    enhancement - expose primitive values/variables or document methods to allow hooking into variables changing

    I used to use this library in objective-c days https://github.com/danielebogo/PRTween Perhaps you could cherry pick helpful stuff.

    I want to hook into a value that gets updated. I want to have a ticker style uilabel that rotates when the length is too long.

    I'm using snapkit through out project / thus far code looks like this (not full functional) I want my label's left offset to change over a duration. eg.

    UIView.animate(
               withDuration:5.0,
               delay: 0.0,
               options: [UIViewAnimationOptions.curveLinear, UIViewAnimationOptions.beginFromCurrentState, UIViewAnimationOptions.repeat],
               animations: {
                  self.labelXoffset = 45 // want a way to hook into a tween value.
                   self.label.snp.updateConstraints { (make) -> Void in
                       make.left.equalTo(self.labelXoffset)
                   }
    
           },
               completion: { _ in
                   
           })
    
    

    https://gist.github.com/johndpope/5eef5fab18ad20b467b8da81032fa83f

    opened by johndpope 9
  • Cancel in flight animation

    Cancel in flight animation

    When we remove an animation from the ActionScheduler, we call didFinish() on it, causing animation to update to its final value.

    Maybe it's the desired behavior but I feel that when you remove an animation you just want to stop it in-flight.

    opened by iDonJose 5
  • Enhancement - ZwischenzugAction / and repeat sequences / use in tableviewcells / collectionviews

    Enhancement - ZwischenzugAction / and repeat sequences / use in tableviewcells / collectionviews

    Thanks for quick response Steve on previous ticket. Heads up - I made a lot of progress on my view rotating label. Here's a peak. https://drive.google.com/file/d/0B-w3I-xzXGu0eFZhTnVLaGNYS3c/view

    a couple things from stand point of consuming the library

    1. not sure if you play chess - but I need a way to have some action in between actions. I looked into the scheduleAction but there was no blocks to inject some method. perhaps you could consider down the track adding such an ZwischenzugAction ? or exposing a block on ScheduledAction or document if it's already possible?.

    2. I see there's a repeat method for actions. - I couldn't see how to do this on a sequence.

    from my code class above

    I have this class https://gist.github.com/johndpope/4897dc5070abce8637886fe9310b9b1b#file-gistfile1-txt-L88

    on last line - I simply want to call let cycleSequence = ActionSequence(actions: moveLeft,bankLabelRight,cycleLeftAgain ) scheduler.run(action: cycleSequence , repeat: forever) // <- keep looping

    1. also - I couldn't see how to remove scheduler actions on destruction of cells. seems like my cells in tableview are being recycled causing some havoc.
    opened by johndpope 5
  • Support Swift Package Manager in Xcode 11

    Support Swift Package Manager in Xcode 11

    👋

    Hey! Appreciate Xcode 11 has only just been published into beta but getting this in early so that when Xcode 11 is released it's not a surprise or last minute job for anyone :)

    Xcode 11 has incredible support for Swift Package Manager, including for iOS projects, and people will be expecting to replace pods with Packages. From what I can see it doesn't look like TweenKit yet supports SPM (which is expected because SPM was never officially supported for iOS until now), so would be good to start thinking about it.

    opened by KaneCheshire 4
  • Added Tweenable CGAffineTransform & CATransform3D

    Added Tweenable CGAffineTransform & CATransform3D

    CGAffineTransform and CATransform3D should be Tweenable. It may produce strange animation for complex transformations, but for simple ones as animating a translation, a scaling or a rotation it is great.

    Example :

    let action = InterpolationAction(from: self.transform,
                                             to: CATransform3DMakeScale(value, value, 1),
                                             duration: duration,
                                             easing: easing,
                                             update: { [weak self] in self?.transform = $0 })
    
    opened by iDonJose 4
  • RepeatForeverAction.update(elapsedTime:) crash

    RepeatForeverAction.update(elapsedTime:) crash

    SDK version: TweenKit (1.0.1) issue: Some iphone devices crashed report from Xcode-Window-Organizer-Crashes. iOS version: 13.1.3,13.3,13.4.1,13.6,13.6.1,14.0 etc. Screenshot is like below: 截屏2020-09-23 下午5 42 51

    It is like that crashes happened at let repeatNumber = Int(elapsedTime / action.duration) So is it possible action.duration to be equal to zero? or other reasons?

    I can not figure it out temporarily, hope you can help. Thank you very much.

    opened by hanweixing 3
  • Ending animations

    Ending animations

    Groups animations when we add it to the ActionScheduler. This offers easier way to replace a bunch a animations.

    Example

    let scheduler = ActionScheduler()
    
    let alphaAction = InterpolationAction...
    let scaleAction = InterpolationAction...
    
    let bounceAnimation = Animation(action: ActionGroup([alphaAction, scaleAction]))
    
    scheduler.add(animation: animation, groupName: "BounceAnimation")
    
    
    /// Later
    
    scheduler.remove(group: "BounceAnimation")
    
    
    opened by iDonJose 3
  • Fixed possible negative duration

    Fixed possible negative duration

    Hello Steve, this is a really a nice framework that your offer us ! In the many animation frameworks available on Github I've chose yours as it's really clean, simple to use and powerful.

    Now comes a bunch of updates I want to bring to better TweenKit !

    Here we fix the duration. It needs to be positive and distance between the two values is algebraic.

    opened by iDonJose 3
  • Ability to monitor elapsedTime

    Ability to monitor elapsedTime

    I'm not sure if this is the preferred way, but we needed a way to detect when an animation was complete, and comparing the elapsed time to the duration accomplished this for us. The only change is to make Animation's elapsedTime property publicly readable. If you would prefer a different approach, please make a suggestion and I'd be happy to work it up.

    opened by ckentgeorge 3
  • Tween CAShapeLayer path?

    Tween CAShapeLayer path?

    Is it possible with this library to create an animation from one path value to another, like with CABasicAnimation, but unlike CABasicAnimation make it scrubbable?

    opened by theoriginalbit 2
Releases(1.0.3)
  • 1.0.3(Sep 28, 2020)

    • Fixes crash when repeating actions with duration of 0.
    • Pauses animation updates whilst backgrounded. This resolves potential crash when returning from the background whilst repeating actions are running.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(Sep 10, 2020)

  • 1.0.1(Sep 6, 2020)

  • 1.0.0(Sep 4, 2020)

    • Swift Package manager support
    • macOS support
    • ActionScheduler can now be initialised with the flag automaticallyAdvanceTime: false, so that time can be instead stepped manually by calling step(dt:)
    Source code(tar.gz)
    Source code(zip)
Owner
Steve Barnegren
Steve Barnegren
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
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
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

Steve Barnegren 1.3k Dec 18, 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
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
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
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

Yuşa Doğru 162 Jan 6, 2023
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
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
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

Caroline Harrison 233 Dec 28, 2022
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

Satoshi Nagasaka 528 Dec 27, 2022
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

Luke Zhao 145 May 28, 2022
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

Draven 1.9k Dec 9, 2022
Gemini is rich scroll based animation framework for iOS, written in Swift.

Overview What is the Gemini? Gemini is rich scroll based animation framework for iOS, written in Swift. You can easily use GeminiCollectionView, which

Shohei Yokoyama 3k Dec 27, 2022
Pulse animation for iOS written with Swift.

Pulsator Pulse animation for iOS written with Swift. Great For: Pulses of Bluetooth, BLE, beacons (iBeacon), etc. Map Annotations Installation CocoaPo

Shuichi Tsutsumi 1.3k Jan 6, 2023
SYBlinkAnimationKit is a blink effect animation framework for iOS, written in Swift.

SYBlinkAnimationKit is a blink effect animation framework for iOS, written in Swift ?? Demo There are 5 types of animation for component. border borde

Shohei Yokoyama 126 Oct 28, 2021
Pulse animation for iOS

Pulsator Pulse animation for iOS written with Swift. Great For: Pulses of Bluetooth, BLE, beacons (iBeacon), etc. Map Annotations Installation CocoaPo

Shuichi Tsutsumi 1.3k Jun 19, 2021