A simple keyframe-based animation framework for iOS, written in Swift. Perfect for scrolling app intros.

Overview

Open Source at IFTTT

RazzleDazzle

Carthage compatible CocoaPods Version

RazzleDazzle is a simple AutoLayout-friendly keyframe animation framework for iOS, written in Swift. Perfect for scrolling app intros.

RazzleDazzle

RazzleDazzle grew from JazzHands, an Objective-C scrolling keyframe animations library by IFTTT.

JazzHands is used extensively in IF and DO for iPhone and iPad, most famously in the app intro.

What's RazzleDazzle for?

Scrolling App Intro Animations

RazzleDazzle is the easiest way to add scrollview-powered animations to the app intro of your Swift app. If you're adding a scrolling intro to your Objective-C app, check out JazzHands!

For some examples of how JazzHands and RazzleDazzle can be used in practice, check out the intros of both IF and DO for iPhone and iPad, as well as the scrolling animations of the buttons in the DO apps by IFTTT.

Easy Paging Scrollview Layouts in an AutoLayout World

RazzleDazzle's keep(view: onPage:) function of the AnimatedPagingScrollViewController is a super easy way to lay out a paging scroll view that does what you expect it to when your app is rotated or used in the new split-screen iPad views of iOS9, a notoriously tricky aspect of getting your apps fully AutoLayout-ready. RazzleDazzle sets up an AutoLayout-friendly paging scroll view controller for you, and all you need to do to make your layout respond properly to any view size changes is tell RazzleDazzle which page you'd like things on.

As a bonus, because it's built on top of the animations library, you can even tell RazzleDazzle that you'd like one of your views to show up on multiple pages while other views scroll past, with a single call to keep(view: onPages:).

Installation

Carthage

RazzleDazzle is available through Carthage. To install it, simply add the following line to your Cartfile:

github "IFTTT/RazzleDazzle"

CocoaPods

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

pod "RazzleDazzle"

Because RazzleDazzle is written in Swift, be sure to add use_frameworks! at the top of your Podfile.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

pod 'RazzleDazzle'

Demo App

Open Example/RazzleDazzle.xcworkspace and run RazzleDazzleDemo to see a simple demonstration of moving, scaling, fading, and transforming views in a scrolling app intro.

Usage

Animated Paging Scroll Views

First, import RazzleDazzle into your view controller, and subclass AnimatedPagingScrollViewController.

import RazzleDazzle

class ViewController: AnimatedPagingScrollViewController {

Tell the paging scroll view controller how many pages it should have.

override func numberOfPages() -> Int {
	return 4
}

Add any views you want to animate to the scrollview's contentView on viewDidLoad.

override func viewDidLoad() {
	super.viewDidLoad()
	contentView.addSubview(firstLabel)
}

Add your desired vertical position and size constraints to your views.

contentView.addConstraint(NSLayoutConstraint(item: firstLabel, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1, constant: 0))

Tell the animated paging scroll view controller to keep the view on the page you want it to stay on.

keepView(firstLabel, onPage: 1)

You can even tell the animated paging scroll view controller to keep the view still on more than one page, while other views scroll past it.

keepView(firstLabel, onPages: [1,2])

Or offset the view's center from the page's center:

keepView(firstLabel, onPage: 1.25)

Just make sure that if you're using any of the keepView functions that you don't set an x-position NSLayoutConstraint on the view, as it will conflict with the animated x-position constraints generated by RazzleDazzle.

RazzleDazzle Animations

Generally, creating animations in RazzleDazzle works similarly to creating animations in JazzHands. First, import RazzleDazzle into your view controller.

import RazzleDazzle

Then, create an Animator to manage all of the animations in this UIViewController.

var animator = Animator()

Create an animation for a view that you want to animate. There are multiple types of animation that can be applied to a view. For this example, we'll use AlphaAnimation, which fades a view in and out.

let alphaAnimation = AlphaAnimation(view: viewThatYouWantToAnimate)

Register the animation with the animator.

animator.addAnimation(alphaAnimation)

Add some keyframes to the animation. Let's fade this view out between times 30 and 60.

alphaAnimation[30] = 1
alphaAnimation[60] = 0

Now, to animate the view, tell the animator what time it is. For example, to tie this animation to a UIScrollView, notify the animator of time in the scroller's delegate method.

func scrollViewDidScroll(_ scrollView: UIScrollView) {
	animator.animate(scrollView.contentOffset.x)
}

This will produce an effect where the view will be fully faded in and visible for scroll positions 0 to 30. Between scroll positions 30 and 60, the view will fade out to be invisible, and it will stay faded out for scroll positions greater than 60.

Animation Types

RazzleDazzle supports several types of animations:

  • AlphaAnimation animates the alpha property (creates fade effects).
  • BackgroundColorAnimation animates the backgroundColor property.
  • RotationAnimation animates a rotation transform (for rotation effects).
  • ScaleAnimation applies a scaling transform (to scale view sizes).
  • TranslationAnimation applies a translation transform (to translate view position).
  • CornerRadiusAnimation animates the layer.cornerRadius property.
  • HideAnimation animates the hidden property (hides and shows views).
  • LayerStrokeStartAnimation animates the strokeStart property of a CAShapeLayer (does not work with LayerStrokeEndAnimation).
  • LayerStrokeEndAnimation animates the strokeEnd property of a CAShapeLayer (does not work with LayerStrokeStartAnimation).
  • LayerFillColorAnimation animates the fillColor property of a CAShapeLayer.
  • LayerStrokeColorAnimation animates the strokeColor property of a CAShapeLayer.
  • PathPositionAnimation animates the layer.position property of a UIView along a path.
  • LabelTextColorAnimation animates the textColor property of a UILabel.
  • ConstraintConstantAnimation animates an AutoLayout constraint constant.
  • ConstraintMultiplierAnimation animates an AutoLayout constraint constant as a multiple of an attribute of another view (to offset or resize views based on another view's size)
  • ScrollViewPageConstraintAnimation animates an AutoLayout constraint constant to place a view on a scroll view page (to position views on a scrollView using AutoLayout). This is the animation doing the heavy lifting for AnimatedPagingScrollViewController's keepView(view: onPage:) function.

Creating Custom Animation Types

RazzleDazzle is easy to extend by creating your own custom animation types!

Custom Animation Types

To create your own custom animation type, your type needs to conform to the Animatable protocol. All this requires is that you implement an animate(time:) function that takes a CGFloat time value and does something with it.

For most custom animations, you'll want to subclass Animation with the specific type of the property you want to interpolate for each keyframe.

public class BorderWidthAnimation : Animation<CGFloat>, Animatable {

Create a property to store whatever view (or other object) you are applying the animations to, and create an initializer that takes a view as input.

private let view : UIView

public init(view: UIView) {
	self.view = view
}

Optionally, you can add a function to validate any input values that will be checked each time a keyframe is added, such as for Alpha values that must range from 0 to 1.

public override func validateValue(_ value: CGFloat) -> Bool {
	return (value >= 0) && (value <= 1)
}

Then, all you need to do is to make the appropriate changes to your view when the animate(time:) function is called.

public func animate(_ time: CGFloat) {
	if !hasKeyframes() {return}
	view.layer.borderWidth = self[time]
}

You can then create an instance of your new Animation in your UIViewController, give it the view you'd like to animate, add it to your Animator and set some keyframes as above, and it will animate your custom property when the Animator is told to animate.

Interpolatable Types

RazzleDazzle can animate any type that conforms to the Interpolatable protocol. It comes pre-cooked to support animating CGFloats, CGPoints, CGSizes, CGRects, and UIColors.

If the property you'd like to animate is of a different type, just extend that type to conform to Interpolatable by adding a static function interpolateFrom(fromValue: toValue: withProgress:) that returns an instance of that type between two other instances of the same type.

extension CGPoint : Interpolatable {
    public static func interpolateFrom(fromValue: CGPoint, to toValue: CGPoint, withProgress progress: CGFloat) -> CGPoint {
        assert((0 <= progress) && (progress <= 1), "Progress must be between 0 and 1")
        let interpolatedX = CGFloat.interpolateFrom(fromValue.x, to: toValue.x, withProgress: progress)
        let interpolatedY = CGFloat.interpolateFrom(fromValue.y, to: toValue.y, withProgress: progress)
        return CGPointMake(interpolatedX, interpolatedY)
    }
}

If your property is a CGFloat or one of the other built-in interpolatable types, you only need to create an animation type that tells RazzleDazzle how to apply the keyframe values to your view, as above.

Notes

An animator can only handle one animation per type per view. If you want multiple animations of the same type on a view, use keyframes of a single animation instead of two separate animations.

RazzleDazzle is written in Swift 3.0, so it will only compile in Xcode 8 and up. If you want to use a library like this that will integrate with an older version of Swift, you can use JazzHands, which is written in Objective-C, and use a bridging header to access the methods from your Swift 1.2 classes.

Looking for libraries to build awesome keyframe animations like RazzleDazzle on Android? Check out SparkleMotion.

Contributors

Contributing

  1. Fork it ( https://github.com/[my-github-username]/RazzleDazzle/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

License

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

Copyright 2015 IFTTT Inc.

Comments
  • xcode 7.3 support for Carthage

    xcode 7.3 support for Carthage

    Can you help to pre-build binaries for Xcode 7.3 and Swift 2.2?

    When i use

    carthage update RazzleDazzle --no-use-binaries

    i always get this error:

    The following build commands failed: CompileSwift normal x86_64 /Users/howie/Git_Repos/Work/Home_iOS/Leo/Carthage/Checkouts/RazzleDazzle/Example/Carthage/Checkouts/Quick/Externals/Nimble/Nimble/Adapters/NimbleXCTestHandler.swift CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler (2 failures)

    opened by howie-misfit 5
  • Xcode 8 GM & Swift 2.3 Support.

    Xcode 8 GM & Swift 2.3 Support.

    Updates the version of dependencies - Quick and Nimble. All targets can be built and be passed all unit tests under Xcode 8 GM (8A218a).

    I didn't optimize core code for Swift 2.3.

    I hope you will merge this PR.

    opened by huinme 3
  • Issue with keeping a view in multiple pages

    Issue with keeping a view in multiple pages

    Hello. I'm not being able to keep a label in multiple pages. I've also tried with a button and the result is the same. What happens is that the view is put way to the left in the scrollview even if only 1 page is set, e.g., keepView(label, pages: [2]). That is, when it should be in page 2 it appears in page 4 or 5 and a bit off center. What could be causing this?

    keepView(label3, onPage: 2) a_keepview_single

    keepView(label3, onPages: [2]) b_keepview_pages

    opened by lm2s 3
  • How I can connect ViewController, that uses RazzleDazzle, with another ViewController correctly

    How I can connect ViewController, that uses RazzleDazzle, with another ViewController correctly

    Hello @lauraskelton, first of all, thanks for this awesome framework :)

    I'm developing an app and I want to connect the introductory part (IntroViewController which uses RazzleDazzle) with a LoginViewController. I try add a UIButton over IntroViewController, but this button don't appear how I expected. How I can connect this Introdutory part with another ViewController correctly?

    cc @FranclinC

    opened by miguelarauj1o 3
  • Not building via Carthage

    Not building via Carthage

    I think this is because it's seeing the .xcworkspace before the .xcodeproj.

    After this is fixed (or even if it's not), could you upload the framework to the latest release?

    All you have to do is:

    $ carthage build --no-skip-current
    
    $ carthage archive RazzleDazzle
    

    Then upload the .zip in project root.

    This will save tons of time on CI servers and will stop problems like this affecting users.

    opened by ky1ejs 3
  • RazzleDazzleDemo using a local folder /Users/laura_ifttt/...

    RazzleDazzleDemo using a local folder /Users/laura_ifttt/...

    Hi, I've just wanted to try the example app in Xcode7b4. So I built RazzleDazzle.framework and then RazzleDazzleDemo. But RazzleDazzleDemo build gives an error since it is looking for the framework in /Users/laura_ifttt/Library/Developer/Xcode/.

    So I had to move the built framework into the RazzleDazzleDemo project to run it. Is this expected or is there any way to point to a relative path?

    opened by gmertk 3
  • Prebuilt binary for Swift 2.1

    Prebuilt binary for Swift 2.1

    Xcode 7.1 prevent the using of prebuilt framework from Xcode 7 with this error:

    Module file was created by an older version of the compiler; rebuild 'RazzleDazzle' and try again: XXX/Carthage/Build/iOS/RazzleDazzle.framework/Modules/RazzleDazzle.swiftmodule/x86_64.swiftmodule

    Would please rebuild it with Xcode 7.1 and archive a new framework for it? Thanks.

    opened by onevcat 2
  • Can an alternative alternatives set of animations be driven by a Pinch Gesture?

    Can an alternative alternatives set of animations be driven by a Pinch Gesture?

    I know that RazzleDazzle basically works with logical time and therefore is inherently linear. This, when tied to the scroll gesture / contentOffset makes for a natural linear animated interaction.

    However, as well as scrolling, I'm interested in letting the user 'zoom out' from that animated interaction so that they see, in effect, a 20,000ft view of the content they were just looking at. i.e. we want to tie animations to a change in zoomLevel as well.

    I just want to confirm, that it's possible to attach, say, TWO (or any number for that matter!) of animators to a View's various different properties?

    e.g.

    x-scroll animates alpha — fades between 0 and 1 y-scroll animates size — scales object frame between 0 and 1

    opened by fatuhoku 2
  • Add animateCurrentFrame to ReadMe Resolves #25

    Add animateCurrentFrame to ReadMe Resolves #25

    Add animateCurrentFrame to the Readme Move and modify the viewDidLoad method example to then end of the block of the instructions to better illustrate the final result of the aforementioned calls

    opened by michaellindahl 1
  • Animations prior to the first frame

    Animations prior to the first frame

    With the IF by IFTT app you can scroll back on the first page and see the animations "reverse" themselves more than their current position. The page indictor also stays centered and does not scroll. When I try replicating this with the test app I run into two issues. First, I'm unable to give the Star animation a negative keyframe. Second, if center something at the bottom on all the pages, it's centered until I scroll before the first page or after the last, in these cases it moves with the scrollview.

    How is this accomplished in the IF by IFTT app?

    opened by michaellindahl 1
  • not (staying) on multiple pages

    not (staying) on multiple pages

    I guess it must be me doing something wrong but while I have it setup like this:

            keepView(pageControl, onPages: [0,1,2])
    

    the page control shows only one the first page.

    BTW: It would be great to mention in the docs whether the pages are 0 or 1 based.

    opened by tcurdt 1
  • Carthage update in project getting terminated

    Carthage update in project getting terminated

    If you run the command: usr/bin/xcrun xcodebuild -workspace Example/RazzleDazzle.xcworkspace -scheme RazzleDazzle -configuration Release -derivedDataPath /Users/apple/Library/Caches/org.carthage.CarthageKit/DerivedData/11.0_11A419c/RazzleDazzle/acfa6d2416614b2efc07669754312c8797442a0c -sdk iphoneos ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= CARTHAGE=YES archive -archivePath /var/folders/w3/m8g_14wd4bz1rtsvn4y7yzhr0000gn/T/RazzleDazzle SKIP_INSTALL=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=NO CLANG_ENABLE_CODE_COVERAGE=NO STRIP_INSTALLED_PRODUCT=NO User defaults from command line: IDEArchivePathOverride = /var/folders/w3/m8g_14wd4bz1rtsvn4y7yzhr0000gn/T/RazzleDazzle IDEDerivedDataPathOverride = /Users/apple/Library/Caches/org.carthage.CarthageKit/DerivedData/11.0_11A419c/RazzleDazzle/acfa6d2416614b2efc07669754312c8797442a0c

    Build settings from command line: CARTHAGE = YES CLANG_ENABLE_CODE_COVERAGE = NO CODE_SIGN_IDENTITY = CODE_SIGNING_REQUIRED = NO GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO ONLY_ACTIVE_ARCH = NO SDKROOT = iphoneos13.0 SKIP_INSTALL = YES STRIP_INSTALLED_PRODUCT = NO

    note: Using new build system note: Planning build note: Constructing build description error: An empty identity is not valid when signing a binary for the product type 'Application'. (in target 'RazzleDazzleDemo' from project 'RazzleDazzleDemo')

    ** ARCHIVE FAILED **

    Please let me know how to fix this @ZevEisenberg @raphaelcruzeiro @maxmeyers

    opened by pushp1989 0
  • Support for Swift 5.0 carthage update

    Support for Swift 5.0 carthage update

    I am getting the following error after i upgrade to Swift 5.0 (XCode 10.2)

    SWIFT_VERSION '3.0' is unsupported, supported versions are: 4.0, 4.2, 5.0. (in target 'RazzleDazzle')

    opened by vijay2pvk 7
  • remove code coverage from production scheme due to LLVM

    remove code coverage from production scheme due to LLVM

    Appstore not requires that in production build code coverage should be disabled. Further discussion on apple developer forum:

    https://forums.developer.apple.com/thread/81893

    When you integrate RazzleDazzle with carthage it will return error:

    Invalid Bundle - Disallowed LLVM instrumentation. Do not submit apps with LLVM profiling instrumentation or coverage collection enabled. Turn off LLVM profiling or code coverage, rebuild your app and resubmit the app.

    After release to the store. Disabling code coverage in scheme setting fix this issue.

    opened by JakubMazur 0
Releases(0.1.5)
Owner
IFTTT
Every thing works better together.
IFTTT
An iOS framework to easily create simple animated walkthrough, written in Swift.

Intro Overview An iOS framework to easily create simple animated walkthrough, written in Swift. Requirements iOS8 Installation with CocoaPods Intro is

Nurdaulet Bolatov 33 Oct 1, 2021
Swift based simple information view with pointed arrow.

InfoView View to show small text information blocks with arrow pointed to another view.In most cases it will be a button that was pressed. Example To

Anatoliy Voropay 60 Feb 4, 2022
Simple coach mark library written in Swift

Minamo Simple coach mark library written in Swift Usage Initialize let rippeleView = RippleView() rippeleView.tintColor = UIColor(red: 0.3, green: 0.7

yukiasai 247 Sep 1, 2022
WVWalkthroughView is an objective C based utility to highlight certain parts for iOS apps.

WVWalkthroughView A simple utility written in Objective C to help developers walk a user through their app. It allows a message to be displayed, a par

Praagya Joshi 29 Mar 25, 2021
iOS library Paper Onboarding is a material design UI slider written on Swift.

iOS library Paper Onboarding is a material design UI slider written on Swift. We specialize in the designing and coding of custom UI

Ramotion 3.2k Nov 20, 2022
SwiftyWalkthrough is a library for creating great walkthrough experiences in your apps, written in Swift.

SwiftyWalkthrough is a library for creating great walkthrough experiences in your apps, written in Swift. You can use the library to allow users to navigate and explore your app, step by step, in a predefined way controlled by you.

Rui Costa 368 Sep 23, 2022
Configurable animated onboarding screen written programmatically in Swift for UIKit

Configurable animated onboarding screen written programmatically in Swift for UIKit – inspired by many Apple-designed user interfaces in iOS – with Insignia as an example.

Lukman “Luke” Aščić 351 Nov 16, 2022
BWWalkthrough is a simple library that helps you build custom walkthroughs for your iOS App

What is BWWalkthrough? BWWalkthrough (BWWT) is a class that helps you create Walkthroughs for your iOS Apps. It differs from other similar classes in

Yari @bitwaker 2.8k Nov 20, 2022
SuggestionsKit is a framework for iOS that was created in order to provide developers with the opportunity to educate users on various features of applications.

SuggestionsKit is a framework for iOS that was created in order to provide developers with the opportunity to educate users

Ilya 62 Nov 20, 2022
A swifty iOS framework that allows developers to create beautiful onboarding experiences.

SwiftyOnboard is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial SwiftyOnboard A simp

Juan Pablo Fernandez 1.2k Nov 20, 2022
An iOS framework to easily create a beautiful and engaging onboarding experience with only a few lines of code.

Onboard Click Here For More Examples Important Onboard is no longer under active development, and as such if you create any issues or submit pull requ

Mike 6.5k Nov 17, 2022
Create walkthroughs and guided tours (coach marks) in a simple way, with Swift.

Add customizable coach marks into your iOS project. Available for both iPhone and iPad. ⚠️ Instructions 2.0.1 brings a couple of breaking changes, ple

Frédéric Maquin 4.9k Nov 15, 2022
A simple and attractive AlertView to onboard your users in your amazing world.

AlertOnboarding A simple and attractive AlertView to onboard your users in your amazing world. PRESENTATION This AlertOnboarding was inspired by this

Boisney Philippe 827 Nov 17, 2022
ColorMix-by-IUKit - colorMix app by Intro to app development in Swift

colorMix-by-IUKit colorMix app by "Intro to app development in Swift" In this ap

null 0 Feb 11, 2022
OnboardKit - Customizable user onboarding for your UIKit app in Swift

OnboardKit Customizable user onboarding for your UIKit app in Swift Requirements Swift 5.0 Xcode 10 iOS 11.0+ Installation Carthage github "NikolaKire

Nikola Kirev 465 Nov 20, 2022
A super-charged version of MYIntroductionView for building custom app introductions and tutorials.

MYBlurIntroductionView #####NOTICE: As of February 4th, Apple has begun to ban new app submissions using the common blurring method (UIToolbar hack) f

Matthew York 1.5k Aug 7, 2022
A nice tutorial like the one introduced in the Path 3.X App

ICETutorial Welcome to ICETutorial. This small project is an implementation of the newly tutorial introduced by the Path 3.X app. Very simple and effi

Icepat 798 Jun 30, 2022
Show overlay and info on app components

SwiftyOverlay App Intro / Instruction component to show data over app UI at run time! Easy to use, Animated and Customizable. Supported Components are

Saeid 80 Aug 29, 2022
Showcase your awesome new app features 📱

WhatsNewKit enables you to easily showcase your awesome new app features. It's designed from the ground up to be fully customized to your needs. Featu

Sven Tiigi 2.8k Nov 20, 2022