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?
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.
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;
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);
}
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);
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;
}