TestsTested | ✓ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | Nov 2015 |
Maintained by Devin Foley, Jonathan Hersh, Laura Skelton.
Jazz Hands is a simple keyframe-based animation framework for UIKit. Animations can be controlled via gestures, scroll views, KVO, or ReactiveCocoa.
Jazz Hands is used extensively in IF and DO by IFTTT for iPhone and iPad, most famously in the app intro.
Open JazzHandsDemo.xcworkspace
to see a simple demonstration of moving, scaling, fading, and transforming views in a scrolling app intro.
To run the example project, clone the repo, and run pod install
from the Example
directory.
Looking to incorporate Jazz Hands into your Swift project? Check out RazzleDazzle
, our brand new scrolling keyframe animations library reimagined in Swift.
You may alternatively just copy the contents of the JazzHands
folder into your project.
First, add JazzHands
to your UIViewController.
#import <IFTTTJazzHands.h>
Now, create an Animator to manage all of the animations in this UIViewController.
@property (nonatomic, strong) IFTTTAnimator *animator;
// later...
self.animator = [IFTTTAnimator new];
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
IFTTTAlphaAnimation
, which fades a view in and out.
IFTTTAlphaAnimation *alphaAnimation = [IFTTTAlphaAnimation animationWithView: viewThatYouWantToAnimate];
Register the animation with the animator.
[self.animator addAnimation: alphaAnimation];
Add some keyframes to the animation. Let's fade this view out between times 30 and 60.
[alphaAnimation addKeyframeForTime:30 alpha:1.f];
[alphaAnimation addKeyframeForTime:60 alpha:0.f];
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.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[super scrollViewDidScroll:scrollView];
[self.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.
Jazz Hands supports several types of animations:
alpha
property (creates fade effects).backgroundColor
property.layer.cornerRadius
property.hidden
property (hides and shows views).layer.transform
property (for 3D transforms).textColor
property of a UILabel
.fillColor
property of a CAShapeLayer
.strokeStart
property of a CAShapeLayer
(does not work with IFTTTStrokeEndAnimation).strokeEnd
property of a CAShapeLayer
(does not work with IFTTTStrokeStartAnimation).layer.position
property of a UIView
.AutoLayout
constraint constant.AutoLayout
constraint constant as a multiple of an attribute of another view (to offset or resize views based on another view's size)
AutoLayout
constraint constant to place a view on a scroll view page (to position views on a scrollView using AutoLayout)
frame
property (moves and sizes views. Not compatible with AutoLayout).JazzHands
's keepView:onPage:
method of the IFTTTAnimatedPagingScrollViewController
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. JazzHands
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 JazzHands
which page you'd like things on.
As a bonus, because it's built on top of the animations library, you can even tell JazzHands
that you'd like one of your views to show up on multiple pages while other views scroll past, with a single call to keepView:onPages:
.
To see the new JazzHands 2.0 AutoLayout magic in action, check out the example project.
Say you want to perform some animations based on a UITableView's scroll offset, but you don't want to be the delegate for that table? ReactiveCocoa is perfect for that.
[RACObserve(self.tableView, contentOffset) subscribeNext:^(NSValue *value) {
CGFloat y = self.tableView.contentOffset.y;
[self.animator animate:y];
}];
Or, maybe you want to animate some views based upon the position of another view? Jazz Hands works well with KVO.
- (void)viewDidLoad
{
[self.viewToMirror addObserver:self
forKeyPath:@"frame"
options:NSKeyValueObservingOptionInitial
context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:@"frame"]) {
[self.animator animate:CGRectGetMinY(self.viewToMirror.frame)];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Jazz Hands is flexible enough that it can accept timer input from many different types of sources, including UIGestureRecognizer
.
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
{
[self.animator animate:[recognizer locationOfTouch:0 inView:self.view].x];
}
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.
IFTTTFrameAnimation is not compatible with AutoLayout or any of the constraint animations.
Looking for libraries to build awesome keyframe animations like JazzHands on Android? Check out SparkleMotion
.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)Copyright 2015 IFTTT Inc.