I have a button with changing text in it.
I want if the button text goes for third line it should reduce its font to minimumScaleFactor.
I am using this code
self.option1Button.titleLabel.minimumScaleFactor = .7;
self.option1Button.titleLabel.numberOfLines = 2;
self.option1Button.titleLabel.adjustsFontSizeToFitWidth = TRUE;
But this is not working. it doesn't change the font size when text reaches to third line.
The adjustToFit will only work for single line labels.
Try doing this:
//Create a string with the text we want to display.
self.ourText = #"This is your variable-length string. Assign it any way you want!";
/* This is where we define the ideal font that the Label wants to use.
Use the font you want to use and the largest font size you want to use. */
UIFont *font = [UIFont fontWithName:#"Marker Felt" size:28];
int i;
/* Time to calculate the needed font size.
This for loop starts at the largest font size, and decreases by two point sizes (i=i-2)
Until it either hits a size that will fit or hits the minimum size we want to allow (i > 10) */
for(i = 28; i > 10; i=i-2) {
// Set the new font size.
font = [font fontWithSize:i];
// You can log the size you're trying: NSLog(#"Trying size: %u", i);
/* This step is important: We make a constraint box
using only the fixed WIDTH of the UILabel. The height will
be checked later. */
CGSize constraintSize = CGSizeMake(260.0f, MAXFLOAT);
// This step checks how tall the label would be with the desired font.
CGSize labelSize = [self.ourText sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
/* Here is where you use the height requirement!
Set the value in the if statement to the height of your UILabel
If the label fits into your required height, it will break the loop
and use that font size. */
if(labelSize.height <= 180.0f)
break;
}
// You can see what size the function is using by outputting: NSLog(#"Best size is: %u", i);
// Set the UILabel's font to the newly adjusted font.
msg.font = font;
// Put the text into the UILabel outlet variable.
msg.text = self.ourText;
If you want your button to display three lines, you will have to set numberOfLines to 3. Strange but true.
I am trying to create a custom cell which consists a few UILabels.
The first label might take one or more rows, so I need to resize the label according to the number of lines (after setting the number of lines to 0, so multi-line will be enabled).
I have tried setting sizeToFit(), but it changed the alignment and width of my label.
I found this answer
but I don't know how to convert it to C#.
Can anyone point me to an example? (I already tried Googling it off-course)
This is the method from the link:
// UILabel *myLabel;
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGFloat labelHeight = labelSize.height;
int lines = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap].height/16;
// '16' is font size
var size = myLabel.StringSize("Some really long string", myLabel.Font, myLabel.Frame.Size, UILineBreakMode.CharacterWrap);
var lines = size.Height / myLabel.Font.CapHeight;
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.
This simple solution works fine for one-line UILabel:
//myLabel - initial label
UILabel *fullSizeLabel = [UILabel new];
fullSizeLabel.font = myLabel.font;
fullSizeLabel.text = myLabel.text;
[fullSizeLabel sizeToFit];
CGFloat actualFontSize = myLabel.font.pointSize * (myLabel.bounds.size.width / fullSizeLabel.bounds.size.width);
//correct, if new font size bigger than initial
actualFontSize = actualFontSize < myLabel.font.pointSize ? actualFontSize : myLabel.font.pointSize;
I have two possible widths for a string i want to display in a label in a table cell, and i need to compute the height so that the table cell's height is recorded correctly. however, no matter what I do for the constraining size i get the same height, which is incorrect in the case i want. The code i'm using:
CGFloat width = 300.0f;
NSString * value = #"LongText LongText LongText LongText LongText LongText";
CGSize contentSize = [value sizeWithFont: [UIFont systemFontOfSize: 14.0f]
constrainedToSize: CGSizeMake(width, CGFLOAT_MAX)
lineBreakMode: UILineBreakModeWordWrap];
When i inspect the contentSize variable, the width is 252 and the height is 36 which is expected. But if instead of 300.0f i plug in 222.0f into the width variable, the width is 189 but the height is still 36, and only the first 4 LongText words are displayed on 2 lines (the third line seems to be cut off somehow in the calculation). Does anyone know why this is happening?
Your code looks right. Look here and here to see if there is anything amiss in your code.
It turns out it is returning the correct size; the code i was working on was using incorrect widths instead of the widths from this method which is why the text was cut off and i was confused.
I have a Uitextview that is populated with a text file. I have a control on the page that allows the user to enable and disable paging. I am having a problem where the top and/or bottom line of the text is sometimes "split in half" so you can only see the top or bottom half of the line. I believe the code below should fix it. The code gets the line height of the text and the frame height, figures out the number of lines that are visible on the screen, and creates a new frame height so it will fit. While the frame does get resized, it still "cuts off" the top and/or bottom line. Anyone one have any suggestions? Is my math wrong?
Thanks!!!
- (void)fitText
{
CGFloat maximumLabelHeight = 338;
CGFloat minimumLabelHeight = 280;
CGSize lineSize = [theUiTextView.text sizeWithFont:theUiTextView.font];
CGFloat lineSizeHeight = lineSize.height;
CGFloat theNumberOfLinesThatShow = theUiTextView.frame.size.height/lineSize.height;
//adjust the label the the new height
theNumberOfLinesThatShow = round(theNumberOfLinesThatShow);
CGFloat theNewHeight = lineSizeHeight * theNumberOfLinesThatShow;
if (theNewHeight > maximumLabelHeight)
{
theNumberOfLinesThatShow = theNumberOfLinesThatShow - 1;
theNewHeight = lineSizeHeight * theNumberOfLinesThatShow;
}
if (theNewHeight < minimumLabelHeight)
{
theNumberOfLinesThatShow = theNumberOfLinesThatShow + 1;
theNewHeight = lineSizeHeight * theNumberOfLinesThatShow;
}
//adjust the label the the new height.
CGRect newFrame = theUiTextView.frame;
newFrame.size.height = theNewHeight;
theUiTextView.frame = newFrame;
}
UIScrollView (and UITextView is a UIScrollView) seems to use a fixed 8-pixel inset on both sides. This seems to be independent of alignment or font size.
So, I think what you're missing here is the fudge factor of 16.0 - see this question.