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
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
}
Related Topics
#Warning: C-Style For Statement Is Deprecated and Will Be Removed in a Future Version of Swift
How to Handle Different Orientations in Ios
Always Pass Weak Reference of Self into Block in Arc
Remove or Uninstall Library Previously Added: Cocoapods
Uibutton Inside a View That Has a Uitapgesturerecognizer
How to Create a Guid/Uuid Using Ios
Getting a List of Files in a Directory With a Glob
Dismiss Keyboard by Touching Background of Uitableview
Detect When an iOS App Is Launched For the First Time
Xcode 6 Beta 2 Issue Exporting .Ipa: "Your Account Already Has a Valid iOS Distribution Certificate"
How to Open Settings Programmatically Like in Facebook App
How to Programmatically Set Device Orientation in iOS 7
Print: Entry, ":Cfbundleidentifier", Does Not Exist
Asynchronous Downloading of Images For Uitableview With Gcd
Detecting Uibutton Pressed in Tableview: Swift Best Practices
Swift 3.1 Deprecates Initialize(). How to Achieve the Same Thing