Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thumb image does not move to the edge of UISlider

Tags:

ios

slider

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?

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
like image 464
Steve Ham Avatar asked Feb 03 '14 06:02

Steve Ham


2 Answers

What you see is the UISlider working as designed, apparently.

By default, at the extreme values, the thumb's edge is aligned with the edges of the track, rather than the thumb's center being positioned on the edge of the track. So this is a problem if you provide a thumb image whose left and right edges are not opaque, since then the track underneath becomes visible.

One partial fix is to override thumbRectForBounds(_:trackRect:value:), so that the thumbs' centers range across the width of the slider. The code below shows this:

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 this is only a partial fix since I do not believe this also modifies the position of the thumb's tap region, so this fix above has the unfortunate side-effect of making the thumbs even less easy to touch than they are by default, since the slider still listens for touches more toward the center of the slider.

like image 109
algal Avatar answered Oct 16 '22 09:10

algal


I recently had to deal with customization of the slider (subclassed), including adding tickmarks on the slider. Thumb image is not centered on the value and since you replaced image it is positioned where it is supposed to be according to implementation. In order to do what you are trying to do I had to adjust position of the thumb image using

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
like image 22
kos Avatar answered Oct 16 '22 09:10

kos