diff --git a/ASValueTrackingSlider/ASValuePopUpView.h b/ASValueTrackingSlider/ASValuePopUpView.h index b9b67fa..c305786 100644 --- a/ASValueTrackingSlider/ASValuePopUpView.h +++ b/ASValueTrackingSlider/ASValuePopUpView.h @@ -13,6 +13,12 @@ #import +typedef NS_ENUM(NSUInteger, ASValuePopUpViewPresentationAnimationType) { + ASValuePopUpViewPresentationAnimationTypeBounce, + ASValuePopUpViewPresentationAnimationTypeFade, + ASValuePopUpViewPresentationAnimationTypeNone, +}; + @protocol ASValuePopUpViewDelegate - (CGFloat)currentValueOffset; //expects value in the range 0.0 - 1.0 - (void)colorDidUpdate:(UIColor *)opaqueColor; @@ -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 \ No newline at end of file diff --git a/ASValueTrackingSlider/ASValuePopUpView.m b/ASValueTrackingSlider/ASValuePopUpView.m index e36765a..45b5b10 100644 --- a/ASValueTrackingSlider/ASValuePopUpView.m +++ b/ASValueTrackingSlider/ASValuePopUpView.m @@ -49,19 +49,6 @@ + (Class)layerClass { return [CAShapeLayer class]; } -// if ivar _shouldAnimate) is YES then return an animation -// otherwise return NSNull (no animation) -- (id )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 )[NSNull null]; -} #pragma mark - public @@ -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 diff --git a/ASValueTrackingSlider/ASValueTrackingSlider.h b/ASValueTrackingSlider/ASValueTrackingSlider.h index 73136fe..6a06a47 100644 --- a/ASValueTrackingSlider/ASValueTrackingSlider.h +++ b/ASValueTrackingSlider/ASValueTrackingSlider.h @@ -7,15 +7,16 @@ // #import +#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; @@ -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; diff --git a/ASValueTrackingSlider/ASValueTrackingSlider.m b/ASValueTrackingSlider/ASValueTrackingSlider.m index 591514f..8a4c620 100644 --- a/ASValueTrackingSlider/ASValueTrackingSlider.m +++ b/ASValueTrackingSlider/ASValueTrackingSlider.m @@ -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 @@ -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]; @@ -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]; } @@ -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; } @@ -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 diff --git a/Example/ValueTrackingSlider/Base.lproj/Main.storyboard b/Example/ValueTrackingSlider/Base.lproj/Main.storyboard index 3706056..eb39bcc 100644 --- a/Example/ValueTrackingSlider/Base.lproj/Main.storyboard +++ b/Example/ValueTrackingSlider/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - - + + @@ -17,27 +17,36 @@ + + + + + + + + + + + + + + - - + - - + - - + - @@ -45,18 +54,21 @@ - + - + + + + @@ -96,6 +108,7 @@ + @@ -120,7 +133,6 @@