The thumb image does not move to the edge of the UISlider

The thumb image does not move to the edge, even when it has a value of max or min.

Does anyone know how to make it move completely to the edge of the slider?

enter image description here

@interface ViewController () @property (weak, nonatomic) IBOutlet UISlider *slider; @end @implementation ViewController - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; UIImage* sliderBarMinImage = [[UIImage imageNamed:@"slider_bar_3_min"] stretchableImageWithLeftCapWidth:8.0 topCapHeight:0.0]; UIImage* sliderBarImage = [[UIImage imageNamed:@"slider_bar_3_max"] stretchableImageWithLeftCapWidth:8.0 topCapHeight:0.0]; UIImage* sliderThumbImage= [[UIImage imageNamed:@"slider_thumb_3"] stretchableImageWithLeftCapWidth:8.0 topCapHeight:0.0]; [self.slider setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal]; [self.slider setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal]; [self.slider setThumbImage:sliderThumbImage forState:UIControlStateNormal]; } @end 
+9
ios slider
source share
8 answers

What you see is a UISlider , working as apparently.

By default, at extreme values, the edge of the thumb is aligned with the edges of the track, not the center of the thumb located on the edge of the track. Thus, this is a problem if you provide an image of the thumb, the left and right edges of which are not opaque, since then the track below it becomes visible.

One partial fix is ​​to redefine thumbRectForBounds(_:trackRect:value:) , so that the centers of the thumbs are located across the width of the slider. The code below shows:

 class CenteredThumbSlider : UISlider { override func thumbRectForBounds(bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect { let unadjustedThumbrect = super.thumbRectForBounds(bounds, trackRect: rect, value: value) let thumbOffsetToApplyOnEachSide:CGFloat = unadjustedThumbrect.size.width / 2.0 let minOffsetToAdd = -thumbOffsetToApplyOnEachSide let maxOffsetToAdd = thumbOffsetToApplyOnEachSide let offsetForValue = minOffsetToAdd + (maxOffsetToAdd - minOffsetToAdd) * CGFloat(value / (self.maximumValue - self.minimumValue)) var origin = unadjustedThumbrect.origin origin.x += offsetForValue return CGRect(origin: origin, size: unadjustedThumbrect.size) } } 

However, I would say that this is only a partial correction, since I do not believe that this also changes the position of the thumb area, so this correction above has an unfortunate side effect, making the thumbs even less easy to touch than they are by default, so how the slider is still listening to touch the center of the slider more.

+10
source share

Recently, I had to deal with setting up a slider (subclass), including adding ticks on the slider. The thumb image is not focused on value, and since you replaced the image, it is located where it should be made in accordance with the implementation. To do what you are trying to do, I had to adjust the position of the thumb with

 - (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value 
+2
source share

Instead

 [self.slider setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal]; [self.slider setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal]; [self.slider setThumbImage:sliderThumbImage forState:UIControlStateNormal]; 

Try setting up a proxy server like this

 [[UISlider appearance] setMinimumTrackImage:sliderBarMinImage forState:UIControlStateNormal]; [[UISlider appearance] setMaximumTrackImage:sliderBarImage forState:UIControlStateNormal]; [[UISlider appearance] setThumbImage:sliderThumbImage forState:UIControlStateNormal]; 
+1
source share

You see that it is already moving to the edge of the slider. This is because the thumb slider has such an angle, so you feel like you are not moving to the edge.

If you want to confirm this, try the same code with a square image in your thumb image.

Hope this helps you.

0
source share

I created a similar slider by creating a subclass of UISlider. In the storyboard, you can set a height limit to increase the height at run time if the thumb of the slider does not receive 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); } 
0
source share

Most of the support answers did not work for me unchanged. Here's what I did - it's replacing the replacement with 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 } } 
0
source share

It may not be the most effective, but it seems to be working fine. This is another easy way to do this in Objective-C. Basically, you will play with the variable "pixelAdjustment" to get the slider where you want.

 - (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; } 
0
source share

I found a simpler solution that also has a pretty smooth UX.

I just set the .highlighted image to the same value as .normal . Here is the code.

  seekBar.setThumbImage(thumbImage, for: .normal) seekBar.setThumbImage(thumbImage, for: .highlighted) 
0
source share

All Articles