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

Support for track background images on lower and upper sides. #78

Open
wants to merge 1 commit 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
6 changes: 6 additions & 0 deletions NMRangeSlider/NMRangeSlider.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
@property (assign, nonatomic) BOOL lowerHandleHidden;
@property (assign, nonatomic) BOOL upperHandleHidden;

@property (assign, nonatomic) BOOL roundedLowerTrackBackground;
@property (assign, nonatomic) BOOL roundedUpperTrackBackground;

@property (assign, nonatomic) float lowerHandleHiddenWidth;
@property (assign, nonatomic) float upperHandleHiddenWidth;

Expand All @@ -73,6 +76,9 @@

@property(retain, nonatomic) UIImage* trackImage;

@property(retain, nonatomic) UIImage* lowerTrackBackgroundImage;
@property(retain, nonatomic) UIImage* upperTrackBackgroundImage;

// track image when lower value is higher than the upper value (eg. when minimum range is negative
@property(retain, nonatomic) UIImage* trackCrossedOverImage;

Expand Down
129 changes: 109 additions & 20 deletions NMRangeSlider/NMRangeSlider.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ @interface NMRangeSlider ()

@property (retain, nonatomic) UIImageView* track;
@property (retain, nonatomic) UIImageView* trackBackground;
@property (retain, nonatomic) UIImageView* lowerTrackBackground;
@property (retain, nonatomic) UIImageView* upperTrackBackground;
@property (assign, nonatomic) CGPoint lowerCenter;
@property (assign, nonatomic) CGPoint upperCenter;

Expand Down Expand Up @@ -70,7 +72,7 @@ - (id) initWithCoder:(NSCoder *)aDecoder

- (void) configureView
{

//Setup the default values
_minimumValue = 0.0;
_maximumValue = 1.0;
Expand All @@ -93,9 +95,9 @@ - (void) configureView

_lowerTouchEdgeInsets = UIEdgeInsetsMake(-5, -5, -5, -5);
_upperTouchEdgeInsets = UIEdgeInsetsMake(-5, -5, -5, -5);

[self addSubviews];

[self.lowerHandle addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
[self.upperHandle addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
}
Expand Down Expand Up @@ -151,7 +153,7 @@ - (void) setUpperValue:(float)upperValue
{
value = roundf(value / _stepValueInternal) * _stepValueInternal;
}

value = MAX(value, _minimumValue);
value = MIN(value, _maximumValue);

Expand All @@ -162,10 +164,19 @@ - (void) setUpperValue:(float)upperValue
value = MAX(value, _lowerValue+_minimumRange);

_upperValue = value;

[self setNeedsLayout];
}

- (void)setRoundedLowerTrackBackground:(BOOL)roundedLowerTrackBackground
{
_roundedLowerTrackBackground = roundedLowerTrackBackground;
}

- (void)setRoundedUpperTrackBackground:(BOOL)roundedUpperTrackBackground
{
_roundedUpperTrackBackground = roundedUpperTrackBackground;
}

- (void) setLowerValue:(float) lowerValue upperValue:(float) upperValue animated:(BOOL)animated
{
Expand Down Expand Up @@ -205,7 +216,7 @@ __block void (^setValuesBlock)(void) = ^ {
{
setValuesBlock();
}

}

- (void)setLowerValue:(float)lowerValue animated:(BOOL) animated
Expand Down Expand Up @@ -319,7 +330,7 @@ - (UIImage *)lowerHandleImageNormal
UIImage *image = [self imageFromBundle:@"slider-default7-handle"];
_lowerHandleImageNormal = [image imageWithAlignmentRectInsets:UIEdgeInsetsMake(-1, 8, 1, 8)];
}

}

return _lowerHandleImageNormal;
Expand Down Expand Up @@ -425,9 +436,9 @@ - (UIEdgeInsets) trackAlignmentInsets
CGFloat lowerOffset = MAX(lowerAlignmentInsets.right, upperAlignmentInsets.left);
CGFloat upperOffset = MAX(upperAlignmentInsets.right, lowerAlignmentInsets.left);

CGFloat leftOffset = MAX(lowerOffset, upperOffset);
CGFloat rightOffset = leftOffset;
CGFloat topOffset = lowerAlignmentInsets.top;
CGFloat leftOffset = MAX(lowerOffset, upperOffset);
CGFloat rightOffset = leftOffset;
CGFloat topOffset = lowerAlignmentInsets.top;
CGFloat bottomOffset = lowerAlignmentInsets.bottom;

return UIEdgeInsetsMake(topOffset, leftOffset, bottomOffset, rightOffset);
Expand Down Expand Up @@ -456,7 +467,7 @@ - (CGRect)trackRect

retValue.origin = CGPointMake(xLowerValue, (self.bounds.size.height/2.0f) - (retValue.size.height/2.0f));
retValue.size.width = xUpperValue-xLowerValue;

UIEdgeInsets alignmentInsets = [self trackAlignmentInsets];
retValue = UIEdgeInsetsInsetRect(retValue,alignmentInsets);

Expand All @@ -476,7 +487,7 @@ - (UIImage*) trackImageForCurrentValues
}

//returns the rect for the background image
-(CGRect) trackBackgroundRect
-(CGRect) trackBackgroundRect
{
CGRect trackBackgroundRect;

Expand All @@ -502,12 +513,70 @@ -(CGRect) trackBackgroundRect
return trackBackgroundRect;
}

//returns the rect for the lower track background image
-(CGRect) lowerTrackBackgroundRect
{
CGRect lowerTrackBackgroundRect;

lowerTrackBackgroundRect.size = CGSizeMake(_lowerTrackBackgroundImage.size.width, _lowerTrackBackgroundImage.size.height);

if(_lowerTrackBackgroundImage.capInsets.top || _lowerTrackBackgroundImage.capInsets.bottom)
{
lowerTrackBackgroundRect.size.height = self.bounds.size.height;
}

float lowerHandleWidth = _lowerHandleHidden ? _lowerHandleHiddenWidth : _lowerHandle.frame.size.width;
float xLowerValue = ((self.bounds.size.width - lowerHandleWidth) * (_lowerValue - _minimumValue) / (_maximumValue - _minimumValue))+(lowerHandleWidth/2.0f);

lowerTrackBackgroundRect.origin = CGPointMake(0.f, (self.bounds.size.height/2.0f) - (lowerTrackBackgroundRect.size.height/2.0f));
lowerTrackBackgroundRect.size.width = xLowerValue;

_lowerTrackBackground.layer.cornerRadius = (self.roundedLowerTrackBackground) ? _lowerTrackBackground.bounds.size.height / 2 : 0;
_lowerTrackBackground.layer.masksToBounds = (self.roundedUpperTrackBackground) ? YES : NO;

// Adjust the track rect based on the image alignment rects

UIEdgeInsets alignmentInsets = [self trackAlignmentInsets];
lowerTrackBackgroundRect = UIEdgeInsetsInsetRect(lowerTrackBackgroundRect, alignmentInsets);

return lowerTrackBackgroundRect;
}

//returns the rect for the upper track background image
-(CGRect) upperTrackBackgroundRect
{
CGRect upperTrackBackgroundRect;

upperTrackBackgroundRect.size = CGSizeMake(_upperTrackBackgroundImage.size.width, _upperTrackBackgroundImage.size.height);

if(_upperTrackBackgroundImage.capInsets.top || _upperTrackBackgroundImage.capInsets.bottom)
{
upperTrackBackgroundRect.size.height=self.bounds.size.height;
}

float upperHandleWidth = _upperHandleHidden ? _upperHandleHiddenWidth : _upperHandle.frame.size.width;
float xUpperValue = ((self.bounds.size.width - upperHandleWidth) * (_upperValue - _minimumValue) / (_maximumValue - _minimumValue))+(upperHandleWidth/2.0f);

upperTrackBackgroundRect.origin = CGPointMake(xUpperValue, (self.bounds.size.height/2.0f) - (upperTrackBackgroundRect.size.height/2.0f));
upperTrackBackgroundRect.size.width = self.bounds.size.width - xUpperValue;

_upperTrackBackground.layer.cornerRadius = (self.roundedUpperTrackBackground) ? _upperTrackBackground.bounds.size.height / 2 : 0;
_upperTrackBackground.layer.masksToBounds = (self.roundedUpperTrackBackground) ? YES : NO;

// Adjust the track rect based on the image alignment rects

UIEdgeInsets alignmentInsets = [self trackAlignmentInsets];
upperTrackBackgroundRect = UIEdgeInsetsInsetRect(upperTrackBackgroundRect,alignmentInsets);

return upperTrackBackgroundRect;
}

//returms the rect of the tumb image for a given track rect and value
- (CGRect)thumbRectForValue:(float)value image:(UIImage*) thumbImage
{
CGRect thumbRect;
UIEdgeInsets insets = thumbImage.capInsets;

thumbRect.size = CGSizeMake(thumbImage.size.width, thumbImage.size.height);

if(insets.top || insets.bottom)
Expand All @@ -519,7 +588,7 @@ - (CGRect)thumbRectForValue:(float)value image:(UIImage*) thumbImage
thumbRect.origin = CGPointMake(xValue, (self.bounds.size.height/2.0f) - (thumbRect.size.height/2.0f));

return CGRectIntegral(thumbRect);

}

// ------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -551,8 +620,21 @@ - (void) addSubviews
self.trackBackground = [[UIImageView alloc] initWithImage:self.trackBackgroundImage];
self.trackBackground.frame = [self trackBackgroundRect];

//------------------------------
// Lower Track Brackground
self.lowerTrackBackground = [[UIImageView alloc] initWithImage:self.lowerTrackBackgroundImage];
self.lowerTrackBackground.frame = [self lowerTrackBackgroundRect];
self.lowerTrackBackground.backgroundColor = [UIColor redColor];

//------------------------------
// Upper Track Brackground
self.upperTrackBackground = [[UIImageView alloc] initWithImage:self.upperTrackBackgroundImage];
self.upperTrackBackground.frame = [self upperTrackBackgroundRect];
self.upperTrackBackground.backgroundColor = [UIColor greenColor];

[self addSubview:self.trackBackground];
[self addSubview:self.lowerTrackBackground];
[self addSubview:self.upperTrackBackground];
[self addSubview:self.track];
[self addSubview:self.lowerHandle];
[self addSubview:self.upperHandle];
Expand All @@ -571,11 +653,18 @@ -(void)layoutSubviews
{
_upperValue = _maximumValue;
}

self.trackBackground.frame = [self trackBackgroundRect];

self.lowerTrackBackground.frame = [self lowerTrackBackgroundRect];
self.upperTrackBackground.frame = [self upperTrackBackgroundRect];

self.lowerTrackBackground.image = self.lowerTrackBackgroundImage;
self.upperTrackBackground.image = self.upperTrackBackgroundImage;

self.track.frame = [self trackRect];
self.track.image = [self trackImageForCurrentValues];

// Layout the lower handle
self.lowerHandle.frame = [self thumbRectForValue:_lowerValue image:self.lowerHandleImageNormal];
self.lowerHandle.image = self.lowerHandleImageNormal;
Expand All @@ -592,7 +681,7 @@ -(void)layoutSubviews

- (CGSize)intrinsicContentSize
{
return CGSizeMake(UIViewNoIntrinsicMetric, MAX(self.lowerHandleImageNormal.size.height, self.upperHandleImageNormal.size.height));
return CGSizeMake(UIViewNoIntrinsicMetric, MAX(self.lowerHandleImageNormal.size.height, self.upperHandleImageNormal.size.height));
}

// ------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -658,7 +747,7 @@ -(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
if(_upperHandle.highlighted )
{
float newValue = [self upperValueForCenterX:(touchPoint.x - _upperTouchOffset)];

//if both upper and lower is selected, then the new value must be HIGHER
//otherwise the touch event is ignored.
if(!_lowerHandle.highlighted || newValue>_upperValue)
Expand All @@ -672,7 +761,7 @@ -(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
_upperHandle.highlighted=NO;
}
}


//send the control event
if(_continuous)
Expand All @@ -682,7 +771,7 @@ -(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

//redraw
[self setNeedsLayout];

return YES;
}

Expand Down