Thumb image does not move to the edge even when it\'s value is max or min.
Does anyone know how to make it move all the way to the edge of the slider?
Instead of
[self.slider setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal];
[self.slider setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal];
[self.slider setThumbImage:sliderThumbImage forState:UIControlStateNormal];
Try setting the appearance proxy like this
[[UISlider appearance] setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal];
[[UISlider appearance] setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal];
[[UISlider appearance] setThumbImage:sliderThumbImage forState:UIControlStateNormal];
Most upvoted answer didn't work for me without changes. Here's what did -- it's a drop in replacement for UISlider
:
class Slider: UISlider {
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float)->CGRect {
var thumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
//determine value dependent offset
var offsetForValue: CGFloat = 0
if value != 0 {offsetForValue = thumbRect.size.width * CGFloat(value / (self.maximumValue - self.minimumValue)) - ((value > 0) ? 2 : -2)}
//apply offset to thumb rect
thumbRect.origin.x += offsetForValue
return thumbRect
}
}
It you see it already moves to the edge of the Slider. Its because thumb image slider have such corner so you feel like its not moving to the edge.
If you want to confirm this that try out the same code with Square image in the thumb image.
I hope it will help you.
So my solution to this problem was to make the colour of the slider Min Track and Max Track transparent and then draw a new track in the initWithCoder and update the size of the track in the continueTrackingWithTouch.
-(AnalogueSlider *)initWithCoder:(NSCoder *)coder :(NSArray *)labels {
self = [super initWithCoder:coder];
trackRect = [self trackRectForBounds:self.bounds];
thumbRect = [self thumbRectForBounds:self.bounds trackRect:trackRect value:self.value];
// drawn a new track
leftTrack = [[UIView alloc] initWithFrame:CGRectMake(trackRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, thumbRect.origin.x-thumbRect.size.width, trackRect.size.height)];
leftTrack.backgroundColor = [UIColor blueColor];
[self insertSubview:leftTrack belowSubview:self];
rightTrack = [[UIView alloc] initWithFrame:CGRectMake(thumbRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, trackRect.size.width-thumbRect.origin.x, trackRect.size.height)];
rightTrack.backgroundColor = [UIColor grayColor];
[self insertSubview:rightTrack belowSubview:self];
return self;
}
-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
thumbRect = [self thumbRectForBounds:self.bounds trackRect:trackRect value:self.value];
leftTrack.frame = CGRectMake(trackRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, thumbRect.origin.x-thumbRect.size.width, trackRect.size.height);
rightTrack.frame = CGRectMake(thumbRect.origin.x+thumbRect.size.width/2.0, trackRect.origin.y, trackRect.size.width-thumbRect.origin.x, trackRect.size.height);
return [super continueTrackingWithTouch:touch withEvent:event];
}
This allows the thumb image to travel further than the track so the centre of the thumb is at the end of the track.
And at the end:
It may not be the most efficient, but it seems to work fine. This is another simple way to do it in Objective-C. Basically, you'll play around with the "pixelAdjustment" variable to get the slider where you want it.
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value: (float)value {
float multValue = value - 0.5;
float pixelAdjustment = 30; //This is the value you need to change depending on the size of the thumb image of your slider.
float xOriginDelta = (multValue * (bounds.size.width - pixelAdjustment));
CGRect adjustedRect = CGRectMake(bounds.origin.x + xOriginDelta, bounds.origin.y, bounds.size.width, bounds.size.height);
return adjustedRect;
}
I have created the similar slider by subclassing UISlider. In storyboard you can set a height constraint to increase height at runtime if slider thumb not gets touch events.
static float const SLIDER_OFFSET = 10.0;
//Get thumb rect for larger track rect than actual to move slider to edges
-(CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {
UIImage *image = self.currentThumbImage;
rect.origin.x -= SLIDER_OFFSET;
rect.size.width += (SLIDER_OFFSET*2);
CGRect thumbRect = [super thumbRectForBounds:bounds trackRect:rect value:value];
return CGRectMake(thumbRect.origin.x, rect.origin.y+2, image.size.width, image.size.height);
}
//Make track rect smaller than bounds
-(CGRect)trackRectForBounds:(CGRect)bounds {
bounds.origin.x += SLIDER_OFFSET;
bounds.size.width -= (SLIDER_OFFSET*2);
CGRect trackRect = [super trackRectForBounds:bounds];
return CGRectMake(trackRect.origin.x, trackRect.origin.y, trackRect.size.width, trackRect.size.height);
}