How to read size of UISlider thumb image

2020-04-05 19:12发布

问题:

I'm trying to position an additional UIView centered above the thumb in a UISlider. To do this, I need the width of the thumb image. In iOS6, this works fine. I can use:

CGFloat thumbWidth = self.navSlider.currentThumbImage.size.width;

(As seen in this answer: How to get the center of the thumb image of UISlider)

This returns 0.0f in iOS7. I've also tried reading it using:

UIImage *thumb = [self.navSlider thumbImageForState:UIControlStateNormal];

But thumb ends up nil.

Is it possible to read the size of the default slider thumb image? Or will I have to find it, set a constant, and how Apple doesn't change it later?

回答1:

The docs on the currentThumbImage property say:

If no custom thumb images have been set using the setThumbImage:forState: method, this property contains the value nil. In that situation, the receiver uses the default thumb image for drawing.

The docs on thumbImageForState: are less clear:

Return Value The thumb image associated with the specified state, or nil if an appropriate image could not be retrieved.

I think you might be out of luck trying to figure out the default thumb size. How about installing a "custom" thumb image that looks exactly like the system image? That would solve the problem of Apple changing it out from under you.



回答2:

I use this in my subclass:

CGRect trackRect = [self trackRectForBounds:self.bounds];
CGRect thumbRect = [self thumbRectForBounds:self.bounds trackRect:trackRect value:0];
CGSize thumbSize = thumbRect.size;


回答3:

You need to set the initial thumb image using setThumbImage forState. This works fine for me in iOS7 and returns the correct width of the image. The slider is setup in a storyboard and connected via an IBOutlet.

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.slider setThumbImage:[UIImage imageNamed:@"tick.jpg"] forState:UIControlStateNormal];

    float check = self.slider.currentThumbImage.size.width;
    NSLog(@"Check is %f", check);

}


回答4:

I believe this will sometimes return 0, if the layout flow hasn't completed. I had some trouble with it.

CGRect thumbRect = [self thumbRectForBounds:self.bounds
                                  trackRect:[self trackRectForBounds:self.bounds]
                                      value:self.value];
CGFloat thumbDiameter = CGRectGetHeight(thumbRect);


回答5:

Here is another one that works, however it is a little "hackier" than the first one, and makes an assumption on the default thumb Image width won't change in future versions of iOS (past 11)

- (CGFloat)thumbImageWidth // default thumb image is 30 px,
{
    double imgThumbImageWidth = self.currentThumbImage.size.width;
    if (imgThumbImageWidth && imgThumbImageWidth != 0 && imgThumbImageWidth != thumbImageWidth) {
        thumbImageWidth = imgThumbImageWidth;
    }
    else if (!thumbImageWidth || thumbImageWidth == 0) { // No custom image set, use 30
        thumbImageWidth = 31;
    }
    return thumbImageWidth;
}