Uilabel - Auto-Size Label to Fit Text

UILabel - auto-size label to fit text?

Please check out my gist where I have made a category for UILabel for something very similar, my category lets a UILabel stretch it's height to show all the content: https://gist.github.com/1005520

Or check out this post: https://stackoverflow.com/a/7242981/662605

This would stretch the height, but you can change it around easily to work the other way and stretch the width with something like this, which is I believe what you want to do:

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
float width = [self expectedWidth];
CGRect newFrame = [self frame];
newFrame.size.width = width;
[self setFrame:newFrame];
}

- (float)expectedWidth{
[self setNumberOfLines:1];

CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

CGSize expectedLabelSize = [[self text] sizeWithFont:[self font]
constrainedToSize:maximumLabelSize
lineBreakMode:[self lineBreakMode]];
return expectedLabelSize.width;
}

@end

You could more simply use the sizeToFit method available from the UIView class, but set the number of lines to 1 to be safe.


iOS 6 update

If you are using AutoLayout, then you have a built in solution. By setting the number of lines to 0, the framework will resize your label appropriately (adding more height) to fit your text.


iOS 8 update

sizeWithFont: is deprecated so use sizeWithAttributes: instead:

- (float)expectedWidth{
[self setNumberOfLines:1];

CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

return expectedLabelSize.width;
}

How to make UILabel resize to fit text

iOS Sample Image 25

see this scrrenshot

1 first select your label width constraint

2 set the relation Greater than or equal

3 set the default constant value here i set it 10

when you change the label text it change the size of label according to its text. hope it's help :)

UILabel is not auto-shrinking text to fit label size

In case you are still searching for a better solution, I think this is what you want:

A Boolean value indicating whether the font size should be reduced in order to fit the title string into the label’s bounding rectangle (this property is effective only when the numberOfLines property is set to 1).

When setting this property, minimumScaleFactor MUST be set too (a good default is 0.5).

Swift

var adjustsFontSizeToFitWidth: Bool { get set }

Objective-C

@property(nonatomic) BOOL adjustsFontSizeToFitWidth;

A Boolean value indicating whether spacing between letters should be adjusted to fit the string within the label’s bounds rectangle.

Swift

var allowsDefaultTighteningForTruncation: Bool { get set }

Objective-C

@property(nonatomic) BOOL allowsDefaultTighteningForTruncation;

Source.

Fit text in UILabel

I think you just need to add this:

label.adjustsFontSizeToFitWidth = YES;
label.minimumFontSize = 0;

Then the text will automatically resize to fit the label.

Note however that this will only really work if the label.numberOfLines = 1, so that the text is on a single line.

If you need the text to wrap onto multiple lines but still shrink to fit, the solution is more complex. To do this, you need to calculate the rendered size of the text and then reduce it in a loop, as follows:

NSString *theText = @"A long string";
CGRect labelRect = CGRectMake(10, 50, 300, 50);
label.adjustsFontSizeToFitWidth = NO;
label.numberOfLines = 0;

CGFloat fontSize = 30;
while (fontSize > 0.0)
{
CGSize size = [theText sizeWithFont:[UIFont fontWithName:@"Verdana" size:fontSize] constrainedToSize:CGSizeMake(labelRect.size.width, 10000) lineBreakMode:UILineBreakModeWordWrap];

if (size.height <= labelRect.size.height) break;

fontSize -= 1.0;
}

//set font size
label.font = [UIFont fontWithName:@"Verdana" size:fontSize];

This basically just reduces the font size until it fits the label.

UPDATE:

As of iOS7, multiline text will also shrink automatically when adjustsFontSizeToFitWidth = YES, so the second part of this answer is no longer needed (unless you still support iOS 6 and earlier).

How to programmatically sizeToFit width AND height on UILabel?

You can do this with boundingRectWithSize...

Add your label to the view and give it a starting width constraint (doesn't really matter what value, as it will be changed).

Keep a reference to that width constraint (IBOutlet works fine if you're using IB).

Don't give it a height constraint.

When you set the text of the label, you can use this to change its width:

// get the font of the label
UIFont *theFont = _theLabel.font;

// get the text of the label
NSString *theString = _theLabel.text;

// calculate the bounding rect, limiting the width to the width of the view
CGRect r = [theString boundingRectWithSize:CGSizeMake(self.view.frame.size.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName: theFont}
context:nil];

// change the constant of the constraint to the calculated width
_theWidthConstraint.constant = ceil(r.size.width);

// NOTE: If you are *not* using auto-layout,
// this same calculation can be used to explicitly set
// the .frame of the label.

Edit:

As per the OP's requirement, a complete, runnable example -- using code only, no storyboards / IB -- can be found here: https://github.com/DonMag/MultilineLabelFitWidth

Edit 2:

GitHub project updated... now includes examples for both manual frame setting and auto layout / constraints.

how to make UILabel autosize text in storyboard (or interface builder), NOT programmatically

On any element in Interface Builder you can select the element and hit...

Editor > Size to Fit Content (keyboard shortcut: CMD+=)

This will do a "sizeToFit" on the selected element. Labels will fit their text size, image view will resize to the image size, etc...

Adjust UILabel height depending on the text

sizeWithFont constrainedToSize:lineBreakMode: is the method to use. An example of how to use it is below:

//Calculate the expected size based on the font and linebreak mode of your label
// FLT_MAX here simply means no constraint in height
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font constrainedToSize:maximumLabelSize lineBreakMode:yourLabel.lineBreakMode];

//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;

Adjust UILabel height to text

I've just put this in a playground and it works for me.

Updated for Swift 4.0

import UIKit

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRectMake(0, 0, width, CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text

label.sizeToFit()
return label.frame.height
}

let font = UIFont(name: "Helvetica", size: 20.0)

var height = heightForView("This is just a load of text", font: font, width: 100.0)

Swift 3:

func heightForView(text:String, font:UIFont, width:CGFloat) -> CGFloat{
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.sizeToFit()

return label.frame.height
}

iOS Sample Image 26



Related Topics



Leave a reply



Submit