How to get UILabel (UITextView) auto adjusted font size?
Is it possible to get final font size, after autoadjusting? (property adjustsFontSizeToFitWidth set to YES, and text font size is being shrinked to fit into the label)
I am subclassing drawTextInRect in UILabel to put gradient on the text, but the gradient size needs to be the same, as the size of the font. I am not able to get proper size of the adjusted font...Is it even possible?
//draw gradient
CGContextSaveGState(myContext);
CGGradientRef glossGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0, 1.0 };
CGFloat components[8] = { 1, 1, 1, 0.25, // BOTTOM color
1, 1, 1, 0.12 }; // UPPER color
//scale and translate so that text would not be rotated 180 deg wrong
CGContextTranslateCTM(myContext, 0, rect.size.height);
CGContextScaleCTM(myContext, 1.0, -1.0);
//create mask
CGImageRef alphaMask = CGBitmapContextCreateImage(myContext);
CGContextClipToMask(myContext, rect, alphaMask);
rgbColorspace = CGColorSpaceCreateDeviceRGB();
glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
//gradient should be sized to actual font size. THIS IS THE PROBLEM - EVEN IF FONT IS AUTO ADUJSTED, I AM GETTING THE SAME ORIGINAL FONT SIZE!!!
CGFloat fontCapHeightHalf = (self.font.capHeight/2)+5;
CGRect currentBounds = rect;
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds)-fontCapHeightHalf);
CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds)+fontCapHeightHalf);
CGContextDrawLinearGradient(myContext, glossGradient, topCenter, midCenter, 0);
CGGradientRelease(glossGradient);
CGColorSpaceRelease(rgbColorspace);
CGContextRestoreGState(myContext);
You can't get the size directly, but you can calculate it easily enough using these functions:
CGFloat actualFontSize;
[label.text sizeWithFont:label.font
minFontSize:label.minimumFontSize
actualFontSize:&actualFontSize
forWidth:label.bounds.size.width
lineBreakMode:label.lineBreakMode];
CGSize size = [label.text sizeWithFont:label.font minFontSize:10 actualFontSize:&actualFontSize forWidth:200 lineBreakMode:UILineBreakModeTailTruncation];
My answer isn't very helpful for the original question, but I end here every time I search how to get the font size after auto adjust.
First of all, sizeWithFont
has been deprecated in iOS 7.0, as we all know, so we have to find another solution.
My solution fits my case, in which I have two labels, one with more constraints and more text than second one.
Here is a step-by-step example:
- two labels with same width and different text length:
I want, at run-time, the font size of the main uilabel to be resized and the second one to have the same font size.
- decrease the size of both labels, so that the text of the first one fits the frame, in this case 12 for both:
- after having set up the position constraints (in my example, the labels stay in the center of the parent view), update the both labels' frames so that they fit the text exactly:
- add the
Aspect Ratio
constraints between width and height to both labels and the width constraint between the main label and the parent view:
- add the width constraint from the second label to the main label:
- now you can set font size of the labels as you wish:
Here is a screenshot of the Simulator:
The first label is resized according to the screen size and the font size is adjusted consequently. The font size of the second label is the same due to the width constraint and the font's parameters specified in the last image.
This is only an example that aims to showcase the "trick" behind my solution: bind the frames of the labels at an initial font size, so that it will be the same at run-time. I imagine that this technique could be re-adapted to labels with a variable size, just by adding the constraints between labels after having set the text and having resized the frame to fit the text.