Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for different slider popUp animations #47

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions ASValueTrackingSlider/ASValuePopUpView.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, ASValuePopUpViewPresentationAnimationType) {
ASValuePopUpViewPresentationAnimationTypeBounce,
ASValuePopUpViewPresentationAnimationTypeFade,
ASValuePopUpViewPresentationAnimationTypeNone,
};

@protocol ASValuePopUpViewDelegate <NSObject>
- (CGFloat)currentValueOffset; //expects value in the range 0.0 - 1.0
- (void)colorDidUpdate:(UIColor *)opaqueColor;
Expand Down Expand Up @@ -44,7 +50,7 @@

- (CGSize)popUpSizeForString:(NSString *)string;

- (void)showAnimated:(BOOL)animated;
- (void)hideAnimated:(BOOL)animated completionBlock:(void (^)())block;
- (void)showWithAnimation:(ASValuePopUpViewPresentationAnimationType)animationType;
- (void)hideWithanimation:(ASValuePopUpViewPresentationAnimationType)animationType completionBlock:(void (^)())block;

@end
95 changes: 44 additions & 51 deletions ASValueTrackingSlider/ASValuePopUpView.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,6 @@ + (Class)layerClass {
return [CAShapeLayer class];
}

// if ivar _shouldAnimate) is YES then return an animation
// otherwise return NSNull (no animation)
- (id <CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key
{
if (_shouldAnimate) {
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:key];
anim.beginTime = CACurrentMediaTime();
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.fromValue = [layer.presentationLayer valueForKey:key];
anim.duration = _animDuration;
return anim;
} else return (id <CAAction>)[NSNull null];
}

#pragma mark - public

Expand Down Expand Up @@ -216,51 +203,57 @@ - (CGSize)popUpSizeForString:(NSString *)string
return CGSizeMake(w, h);
}

- (void)showAnimated:(BOOL)animated
- (void)showWithAnimation:(ASValuePopUpViewPresentationAnimationType)animationType
{
if (!animated) {
self.layer.opacity = 1.0;
return;
void(^fadeAnimation)() = ^{ self.alpha = 1.0; };
void (^expandAnimation)() = ^{ self.transform = CGAffineTransformIdentity; };

switch (animationType) {
case ASValuePopUpViewPresentationAnimationTypeBounce:
self.transform = CGAffineTransformMakeScale(0.5, 0.5);
[UIView animateWithDuration:0.4 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:0 animations:expandAnimation completion:nil];
// Don't break here because we'll fall through to run the fade along with the bounce

case ASValuePopUpViewPresentationAnimationTypeFade:
[UIView animateWithDuration:0.4 animations:fadeAnimation];
break;

case ASValuePopUpViewPresentationAnimationTypeNone:
default:
fadeAnimation();
expandAnimation();
break;
}

[CATransaction begin]; {
// start the transform animation from scale 0.5, or its current value if it's already running
NSValue *fromValue = [self.layer animationForKey:@"transform"] ? [self.layer.presentationLayer valueForKey:@"transform"] : [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];

[self.layer animateKey:@"transform" fromValue:fromValue toValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]
customize:^(CABasicAnimation *animation) {
animation.duration = 0.4;
animation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.8 :2.5 :0.35 :0.5];
}];

[self.layer animateKey:@"opacity" fromValue:nil toValue:@1.0 customize:^(CABasicAnimation *animation) {
animation.duration = 0.1;
}];
} [CATransaction commit];
}

- (void)hideAnimated:(BOOL)animated completionBlock:(void (^)())block
- (void)hideWithanimation:(ASValuePopUpViewPresentationAnimationType)animationType completionBlock:(void (^)())block
{
[CATransaction begin]; {
[CATransaction setCompletionBlock:^{
void(^fadeAnimation)() = ^{ self.alpha = 0.0; };
void (^shrinkAnimation)() = ^{ self.transform = CGAffineTransformMakeScale(0.2, 0.2); };
void (^shrinkCompletion)(BOOL) = ^(BOOL finished) {
self.transform = CGAffineTransformIdentity;
if (block) {
block();
self.layer.transform = CATransform3DIdentity;
}];
if (animated) {
[self.layer animateKey:@"transform" fromValue:nil
toValue:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)]
customize:^(CABasicAnimation *animation) {
animation.duration = 0.55;
animation.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.1 :-2 :0.3 :3];
}];

[self.layer animateKey:@"opacity" fromValue:nil toValue:@0.0 customize:^(CABasicAnimation *animation) {
animation.duration = 0.75;
}];
} else { // not animated - just set opacity to 0.0
self.layer.opacity = 0.0;
}
} [CATransaction commit];
};

switch (animationType) {
case ASValuePopUpViewPresentationAnimationTypeBounce:
[UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.6 initialSpringVelocity:-5 options:0 animations:shrinkAnimation completion:shrinkCompletion];
[UIView animateWithDuration:0.3 animations:fadeAnimation];
break;

case ASValuePopUpViewPresentationAnimationTypeFade:
[UIView animateWithDuration:0.3 animations:fadeAnimation completion:shrinkCompletion];
break;

case ASValuePopUpViewPresentationAnimationTypeNone:
default:
fadeAnimation();
shrinkAnimation();
shrinkCompletion(YES);
break;
}
}

#pragma mark - CAAnimation delegate
Expand Down
11 changes: 9 additions & 2 deletions ASValueTrackingSlider/ASValueTrackingSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
//

#import <UIKit/UIKit.h>
#import "ASValuePopUpView.h"
@protocol ASValueTrackingSliderDelegate;
@protocol ASValueTrackingSliderDataSource;

@interface ASValueTrackingSlider : UISlider

// present the popUpView manually, without touch event.
- (void)showPopUpViewAnimated:(BOOL)animated;
- (void)showPopUpView;
// the popUpView will not hide again until you call 'hidePopUpViewAnimated:'
- (void)hidePopUpViewAnimated:(BOOL)animated;
- (void)hidePopUpView;

@property (strong, nonatomic) UIColor *textColor;

Expand Down Expand Up @@ -49,6 +50,12 @@
// the track color alpha is always set to 1.0, even if popUpView color is less than 1.0
@property (nonatomic) BOOL autoAdjustTrackColor; // (default is YES)

// set this flag to disable the popUp from showing when the slider is touched.
@property (nonatomic) BOOL popUpViewEnabled; // (defaults to YES)

// use this enum to change the animation style when the popup view shows and hides
@property (nonatomic) ASValuePopUpViewPresentationAnimationType popUpViewPresentationAnimationType; // defaults to "bounce"

// when setting max FractionDigits the min value is automatically set to the same value
// this ensures that the PopUpView frame maintains a consistent width
- (void)setMaxFractionDigitsDisplayed:(NSUInteger)maxDigits;
Expand Down
24 changes: 13 additions & 11 deletions ASValueTrackingSlider/ASValueTrackingSlider.m
Original file line number Diff line number Diff line change
Expand Up @@ -184,16 +184,16 @@ - (NSNumberFormatter *)numberFormatter
return [_numberFormatter copy]; // return a copy to prevent formatter properties changing and causing mayhem
}

- (void)showPopUpViewAnimated:(BOOL)animated
- (void)showPopUpView
{
self.popUpViewAlwaysOn = YES;
[self _showPopUpViewAnimated:animated];
[self _showPopUpView];
}

- (void)hidePopUpViewAnimated:(BOOL)animated
- (void)hidePopUpView
{
self.popUpViewAlwaysOn = NO;
[self _hidePopUpViewAnimated:animated];
[self _hidePopUpView];
}

#pragma mark - ASValuePopUpViewDelegate
Expand All @@ -216,6 +216,8 @@ - (void)setup
_autoAdjustTrackColor = YES;
_valueRange = self.maximumValue - self.minimumValue;
_popUpViewAlwaysOn = NO;
_popUpViewPresentationAnimationType = ASValuePopUpViewPresentationAnimationTypeBounce;
_popUpViewEnabled = YES;

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
Expand Down Expand Up @@ -302,18 +304,18 @@ - (CGRect)thumbRect
value:self.value];
}

- (void)_showPopUpViewAnimated:(BOOL)animated
- (void)_showPopUpView
{
if (self.delegate) [self.delegate sliderWillDisplayPopUpView:self];
[self.popUpView showAnimated:animated];
[self.popUpView showWithAnimation:_popUpViewPresentationAnimationType];
}

- (void)_hidePopUpViewAnimated:(BOOL)animated
- (void)_hidePopUpView
{
if ([self.delegate respondsToSelector:@selector(sliderWillHidePopUpView:)]) {
[self.delegate sliderWillHidePopUpView:self];
}
[self.popUpView hideAnimated:animated completionBlock:^{
[self.popUpView hideWithanimation:_popUpViewPresentationAnimationType completionBlock:^{
if ([self.delegate respondsToSelector:@selector(sliderDidHidePopUpView:)]) {
[self.delegate sliderDidHidePopUpView:self];
}
Expand Down Expand Up @@ -380,7 +382,7 @@ - (void)setMinimumTrackTintColor:(UIColor *)color
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
BOOL begin = [super beginTrackingWithTouch:touch withEvent:event];
if (begin && !self.popUpViewAlwaysOn) [self _showPopUpViewAnimated:YES];
if (begin && !self.popUpViewAlwaysOn && self.popUpViewEnabled) [self _showPopUpView];
return begin;
}

Expand All @@ -398,13 +400,13 @@ - (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
- (void)cancelTrackingWithEvent:(UIEvent *)event
{
[super cancelTrackingWithEvent:event];
if (self.popUpViewAlwaysOn == NO) [self _hidePopUpViewAnimated:YES];
if (self.popUpViewAlwaysOn == NO) [self _hidePopUpView];
}

- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
if (self.popUpViewAlwaysOn == NO) [self _hidePopUpViewAnimated:YES];
if (self.popUpViewAlwaysOn == NO) [self _hidePopUpView];
}

@end
Loading