views:

872

answers:

4

I'm creating a custom UISlider to test out some interface ideas. Mostly based around making the thumb image larger.

I found out how to do that, like so:

UIImage *thumb = [UIImage imageNamed:@"newThumbImage_64px.png"];  
[self.slider setThumbImage:thumb forState:UIControlStateNormal];  
[self.slider setThumbImage:thumb forState:UIControlStateHighlighted];  
[thumb release];

To calculate a related value I need to know where the center point of the thumb image falls when it's being manipulated. And the point should be in it's superview's coordinates.

Looking at the UISlider docs, I didn't see any property that tracked this.

Is there some easy way to calculate this or can it be derived from some existing value(s)?

+2  A: 

AFter a little playing with IB and a 1px wide thumb image, the position of the thumb is exactly where you'd expect it:

UIImage       *thumb = [UIImage imageNamed:@"newThumbImage_64px.png"];  
CGRect        sliderFrame = self.slider.frame;
CGFloat       x = sliderFrame.origin.x + slideFrame.size.width * slider.value + thumb.size.width / 2;
CGFloat       y = sliderFrame.origin.y + sliderFrame.size.height / 2;

return CGPointMake(x, y);
Ben Gottlieb
Assuming slider range 0..1, your point is correct when the slider.value is 0, but gets more off as slider.value changes. Also, there's a typo in the x equation.
willc2
willc2
Oops, sorry about the typo, fixed.
Ben Gottlieb
Still not getting the right value. When testing, I'm setting a transparent view's center point using your computed x,y point.
willc2
Upon further testing, it appears there's a 1-4px adjustment, depending on where on the slider you are. I've posted my test code here: http://dl.dropbox.com/u/85235/ThumbTest.zip. Using it and xScope, you can play around and find the exact values.
Ben Gottlieb
+4  A: 

This will return the correct X position of center of thumb image of UISlider in view coordinates:

- (float)xPositionFromSliderValue:(UISlider *)aSlider;
{
 float sliderRange = aSlider.frame.size.width - aSlider.currentThumbImage.size.width;
 float sliderOrigin = aSlider.frame.origin.x + (aSlider.currentThumbImage.size.width / 2.0);

 float sliderValueToPixels = (aSlider.value * sliderRange) + sliderOrigin;

 return sliderValueToPixels;
}

Put it in your view controller and use it like this: (assumes ivar named slider)

float x = [self xPositionFromSliderValue:self.slider.value];
willc2
this works for me, except for needing one change to allow for sliders with custom min/max values: float sliderValueToPixels = (aSlider.value/aSlider.maximumValue * sliderRange) + sliderOrigin;Also, it is called like so: float x = [self xPositionFromSliderValue:someSlider];
jenningj
+3  A: 

I approached it by first mapping the UISlider's value interval in percents and then taking the same percent of the slider's size minus the percent of the thumb's size, a value to which I added half of the thumb's size to obtain its center.

    - (float)mapValueInIntervalInPercents: (float)value min: (float)minimum max: (float)maximum
    {
        return (100 / (maximum - minimum)) * value -
               (100 * minimum)/(maximum - minimum);
    }    


    - (float)xPositionFromSliderValue:(UISlider *)aSlider
    {
        float percent = [self mapValueInIntervalInPercents: aSlider.value
                              min: aSlider.minimumValue
                              max: aSlider.maximumValue] / 100.0;

        return percent * aSlider.frame.size.width -
               percent * aSlider.currentThumbImage.size.width +
               aSlider.currentThumbImage.size.width / 2;
    }
luvieere
A: 

I would like to know why none of you provide the simplest answer which consist in reading the manual. You can compute all these values accurately and also MAKING SURE THEY TAY THAT WAY, by simply using the methods:

- (CGRect)trackRectForBounds:(CGRect)bounds
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value

which you can easily found in developer documentation.

If you thumb image changes and you want to change how it's positioned, you subclass and override these methods. The first one gives you the rectangle in which the thumb can move the second one the position of the thumb itself.

Psycho