UILabel - auto-size label to fit text?
IosIphoneObjective CUilabelIos Problem Overview
Is it possible to auto-resize the UILabel box/bounds to fit the contained text? (I don't care if it ends up larger than the display)
So if a user enters "hello" or "my name is really long i want it to fit in this box", it is never truncated and the label is 'widened' accordingly?
Ios Solutions
Solution 1 - Ios
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;
}
Solution 2 - Ios
Using [label sizeToFit];
will achieve the same result from Daniels Category.
Although I recommend to use autolayout and let the label resize itself based on constraints.
Solution 3 - Ios
If we want that UILabel
should shrink and expand based on text size then storyboard with autolayout is best option. Below are the steps to achieve this
Steps
-
Put UILabel in view controller and place it wherever you want. Also put
0
fornumberOfLines
property ofUILabel
. -
Give it Top, Leading and Trailing space pin constraint.
- Now it will give warning, Click on the yellow arrow.
- Click on
Update Frame
and click onFix Misplacement
. Now this UILabel will shrink if text is less and expand if text is more.
Solution 4 - Ios
This is not as complicated as some of the other answers make it.
#Pin the left and top edges
Just use auto layout to add constraints to pin the left and top sides of the label.
After that it will automatically resize.
Notes
-
Don't add constraints for the width and height. Labels have an intrinsic size based on their text content.
-
Thanks to this answer for help with this.
-
No need to set
sizeToFit
when using auto layout. My complete code for the example project is here:import UIKit class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! @IBAction func changeTextButtonTapped(sender: UIButton) { myLabel.text = "my name is really long i want it to fit in this box" } }
-
If you want your label to line wrap then set the number of lines to 0 in IB and add
myLabel.preferredMaxLayoutWidth = 150 // or whatever
in code. (I also pinned my button to the bottom of the label so that it would move down when the label height increased.)
- If you are looking for dynamically sizing labels inside a
UITableViewCell
then see this answer.
Solution 5 - Ios
Use [label sizeToFit];
to adjust the text in UILabel
Solution 6 - Ios
Here's what I am finding works for my situation:
-
The height of the UILabel has a >= 0 constraint using autolayout. The width is fixed.
-
Assign the text into the UILabel, which already has a superview at that point (not sure how vital that is).
-
Then, do:
label.sizeToFit() label.layoutIfNeeded()
The height of the label is now set appropriately.
Solution 7 - Ios
I created some methods based Daniel's reply above.
-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
CGSize maximumLabelSize = CGSizeMake(290, FLT_MAX);
CGSize expectedLabelSize = [text sizeWithFont:label.font
constrainedToSize:maximumLabelSize
lineBreakMode:label.lineBreakMode];
return expectedLabelSize.height;
}
-(void)resizeHeightToFitForLabel:(UILabel *)label
{
CGRect newFrame = label.frame;
newFrame.size.height = [self heightForLabel:label withText:label.text];
label.frame = newFrame;
}
-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
label.text = text;
[self resizeHeightToFitForLabel:label];
}
Solution 8 - Ios
@implementation UILabel (UILabel_Auto)
- (void)adjustHeight {
if (self.text == nil) {
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
return;
}
CGSize aSize = self.bounds.size;
CGSize tmpSize = CGRectInfinite.size;
tmpSize.width = aSize.width;
tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}
@end
This is category method. You must set text first, than call this method to adjust UILabel's height.
Solution 9 - Ios
You can size your label according to text and other related controls using two ways-
-
For iOS 7.0 and above
CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName : labelFont } context:nil].size;
before iOS 7.0 this could be used to calculate label size
CGSize labelTextSize = [label.text sizeWithFont:label.font
constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)
lineBreakMode:NSLineBreakByWordWrapping];
// reframe other controls based on labelTextHeight
CGFloat labelTextHeight = labelTextSize.height;
2. If you do not want to calculate the size of the label's text than you can use -sizeToFit on the instance of UILabel as-
[label setNumberOfLines:0]; // for multiline label
[label setText:@"label text to set"];
[label sizeToFit];// call this to fit size of the label according to text
// after this you can get the label frame to reframe other related controls
Solution 10 - Ios
- Add missing constraints in storyboard.
- Select UILabel in storyboard and set the attributes "Line" to 0.
- Ref Outlet the UILabel to Controller.h with id:label
- Controller.m and add
[label sizeToFit];
in viewDidLoad
Solution 11 - Ios
the sizeToFit() method doesn't play well with constraints, but as of iOS 9 this is all you need -
label.widthAnchor.constraint(equalToConstant: label.intrinsicContentSize.width).activate()
Solution 12 - Ios
I had a huge problems with auto layout. We have two containers inside table cell. Second container is resized depending on Item description (0 - 1000 chars), and row should be resized based on them.
The missing ingredient was bottom constraint for description.
I've changed bottom constraint of dynamic element from = 0 to >= 0.
Solution 13 - Ios
Fits everytime! :)
name.text = @"Hi this the text I want to fit to"
UIFont * font = 14.0f;
CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
nameOfAssessment.font = [UIFont systemFontOfSize:font];
Solution 14 - Ios
you can show one line output then set property Line=0 and show multiple line output then set property Line=1 and more
[self.yourLableName sizeToFit];
Solution 15 - Ios
There's also this approach:
[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];