[iphone] UILabel is not auto-shrinking text to fit label size

I have this strange issue, and im dealing with it for more than 8 hours now.. Depending on situation i have to calculate UILabels size dynamically,
e.g
my UIViewController receives an event and i change UILabels size. from bigger to smaller. The size of my UILabel gets smaller and i get the correct needed size, but the text in my UILabel stays the same, the same font size and etc. I need the font to get smaller, for the whole text to fit the UILabel. So the question is how to make the text to fit my label with autoshrinking or something like that?

In my xib, UILabels autoshrink is checked, also number of lines is set to 0, and also my string has new line symbols (\n), and i've selected linebreakmode to wordwrap. Maybe anyone was in the same situation as i am now, and could help me? I would really appreciate that.

Thank's in advance!

EDIT: UILabel minimum font size is set to 10

This question is related to iphone objective-c ios cocoa-touch ipad

The answer is


This is how I get UILabel Autoshrink work (especially for height of label font fitting in 4s device from 6s Plus Storyboard) in iOS 9.2, Xcode 7.2 ...

enter image description here

  • Number of lines is 0
  • Line Breaks: Clip
  • Autoshrink: Minimum Font Scale 0.25

In Swift 3 (Programmatically) I had to do this:

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)

Well in the end i didn't find my answer. And i think the autoshrink doesn't work for multiple lines. I ended up using suggestion in this link: autoshrink on a UILabel with multiple lines

The solutions is to calulate text height at given width and if text is bigger, to shrink font size and then do he same again until the height is equal or less than your needed size.

I don't understand why this should be so hard to implement. If i'm missing something, everyone is welcome to correct me :)


Here's how to do it.Suppose the following messageLabel is the label you want to have the desired effect.Now,try these simple line of codes:

    //SET THE WIDTH CONSTRAINTS FOR LABEL.
    CGFloat constrainedWidth = 240.0f;//YOU CAN PUT YOUR DESIRED ONE,THE MAXIMUM WIDTH OF YOUR LABEL.
 //CALCULATE THE SPACE FOR THE TEXT SPECIFIED.
    CGSize sizeOfText=[yourText sizeWithFont:yourFont constrainedToSize:CGSizeMake(constrainedWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    UILabel *messageLabel=[[UILabel alloc] initWithFrame:CGRectMake(20,20,constrainedWidth,sizeOfText.height)];
    messageLabel.text=yourText;
    messageLabel.numberOfLines=0;//JUST TO SUPPORT MULTILINING.

It's a great question, because it feels like that would be part of the built-in UIKit functionality or a related framework by now. Here's a good visual example of the question:

Font resizing animation

There's no easy way around it, but it's definitely possible. One way to do this is to programmatically try different font sizes until you find one that fits reasonably close to the bounds of the view. You can accomplish this with the boundingRect() function of NSString or NSAttributedString. For example:

let string = "This is a test"
let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height:CGFloat.greatestFiniteMagnitude)
let size = string.boundingRect(with: infiniteSize, options: [], attributes: [.font: UIFont.systemFont(ofSize: avgSize)] context: nil).size

You can do a binary search to be more efficient than a complete brute force approach. There are also some considerations that are a bit more involved, including correct word wrapping and iOS font caching performance, if you're looking for something really robust.

If you only care about showing the text on the screen in an easy way, I have developed a robust implementation in Swift, which I'm also using in a production app. It's a UIView subclass with efficient, automatic font scaling for any input text, including multiple lines. To use it, you'd simply do something like:

let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere

That's it! You can find the complete source here: https://github.com/FlickType/AccessibilityKit

Hope this helps!


You can write like

UILabel *reviews = [[UILabel alloc]initWithFrame:CGRectMake(14, 13,270,30)];//Set frame
reviews.numberOfLines=0;
reviews.textAlignment = UITextAlignmentLeft;
reviews.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:12];
reviews.textColor=[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.8]; 
reviews.backgroundColor=[UIColor clearColor];

You can calculate number of lines like that

CGSize maxlblSize = CGSizeMake(270,9999);
CGSize totalSize = [reviews.text sizeWithFont:reviews.font 
              constrainedToSize:maxlblSize lineBreakMode:reviews.lineBreakMode];

CGRect newFrame =reviews.frame;
newFrame.size.height = totalSize.height;
reviews.frame = newFrame;

CGFloat reviewlblheight = totalSize.height;

int lines=reviewlblheight/12;//12 is the font size of label

UILabel *lbl=[[UILabel alloc]init];
lbl.frame=CGRectMake(140,220 , 100, 25);//set frame as your requirement
lbl.font=[UIFont fontWithName:@"Arial" size:20];
[lbl setAutoresizingMask:UIViewContentModeScaleAspectFill];
[lbl setLineBreakMode:UILineBreakModeClip];
lbl.adjustsFontSizeToFitWidth=YES;//This is main for shrinking font
lbl.text=@"HelloHelloHello";

Hope this will help you :-) waiting for your reply


In iOS 9 I just had to:

  1. Add constraints from the left and right of the label to the superview.
  2. Set the line break mode to clipping in IB.
  3. Set the number of lines to 1 in IB.

Someone recommended setting number of lines to 0, but for me this just made the label go to multiple lines...


does not work if numberOfLines > 1 What i did made a condition like this-

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];

also my solution is the boolean label.adjustsFontSizeToFitWidth = YES; BUT. You must in the interface Builder the Word Wrapping switch to "CLIP". Then autoshrink the Labels. This is very important.


Two years on, and this issue is still around...

In iOS 8 / XCode 6.1, I was sometimes finding that my UILabel (created in a UITableViewCell, with AutoLayout turned on, and flexible constraints so it had plenty of space) wouldn't resize itself to fit the text string.

The solution, as in previous years, was to set the text, and then call sizeToFit.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    . . .
    cell.lblCreatedAt.text = [note getCreatedDateAsString];
    [cell.lblCreatedAt sizeToFit];
}

(Sigh.)


Coming late to the party, but since I had the additional requirement of having one word per line, this one addition did the trick for me:

label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;

Apple Docs say:

Normally, the label text is drawn with the font you specify in the font property. If this property is set to YES, however, and the text in the text property exceeds the label’s bounding rectangle, the receiver starts reducing the font size until the string fits or the minimum font size is reached. In iOS 6 and earlier, this property is effective only when the numberOfLines property is set to 1.

But this is a lie. A lie I tell you! It's true for all iOS versions. Specifically, this is true when using a UILabel within a UICollectionViewCell for which the size is determined by constraints adjusted dynamically at runtime via custom layout (ex. self.menuCollectionViewLayout.itemSize = size).

So when used in conjunction with adjustsFontSizeToFitWidth and minimumScaleFactor, as mentioned in previous answers, programmatically setting numberOfLines based on word count solved the autoshrink problem. Doing something similar based on word count or even character count might produce a "close enough" solution.


In Swift 4 (Programmatically):

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200.0, height: 200.0))
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0

label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

view.addSubview(label)

Swift 4, Xcode 9.4.1

The solution that worked for me: I had a label within a collection view cell, and the label text was getting trimmed. Set the attributes as below on Storyboard

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)

This is for Swift 3 running Xcode 8.2.1 ( 8C1002 )

The best solution that I've found is to set a fixed width in your Storyboard or IB on the label. Set your constraints with constrain to margins. In your viewDidLoad add the following lines of code:

override func viewDidLoad() {
            super.viewDidLoad()

            label.numberOfLines = 1
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.5
        }

label constraints to margin

fixed width label constraints to margin

attributes inspector

This worked like a charm and it doesn't overflow to a new line and shrinks the text to fit the width of the label without any weird issues and works in Swift 3.


I think you can write bellow code after alloc init Label

UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, 280, 50)];
lbl.text = @"vbdsbfdshfisdhfidshufidhsufhdsf dhdsfhdksbf hfsdh fksdfidsf sdfhsd fhdsf sdhfh sdifsdkf ksdhfkds fhdsf dsfkdsfkjdhsfkjdhskfjhsdk fdhsf ";
[lbl setMinimumFontSize:8.0];
[lbl setNumberOfLines:0];
[lbl setFont:[UIFont systemFontOfSize:10.0]];
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.backgroundColor = [UIColor redColor];
[lbl sizeToFit];
[self.view addSubview:lbl];

It is working with me fine Use it


minimumFontSize is deprecated in iOS 6.

So use minimumScaleFactor instead of minmimumFontSize.

lbl.adjustsFontSizeToFitWidth = YES
lbl.minimumScaleFactor = 0.5

Swift 5

lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5

Examples related to iphone

Detect if the device is iPhone X Xcode 8 shows error that provisioning profile doesn't include signing certificate Access files in /var/mobile/Containers/Data/Application without jailbreaking iPhone Certificate has either expired or has been revoked Missing Compliance in Status when I add built for internal testing in Test Flight.How to solve? cordova run with ios error .. Error code 65 for command: xcodebuild with args: "Could not find Developer Disk Image" Reason: no suitable image found iPad Multitasking support requires these orientations How to insert new cell into UITableView in Swift

Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to cocoa-touch

Include of non-modular header inside framework module Move textfield when keyboard appears swift Create space at the beginning of a UITextField Navigation bar with UIImage for title Generate a UUID on iOS from Swift How do I write a custom init for a UIView subclass in Swift? creating custom tableview cells in swift How would I create a UIAlertView in Swift? Get current NSDate in timestamp format How do you add an in-app purchase to an iOS application?

Examples related to ipad

What is correct media query for IPad Pro? iPad Multitasking support requires these orientations How to restrict UITextField to take only numbers in Swift? How to present a modal atop the current view in Swift Presenting a UIAlertController properly on an iPad using iOS 8 Detect current device with UI_USER_INTERFACE_IDIOM() in Swift HTML5 Video tag not working in Safari , iPhone and iPad Install .ipa to iPad with or without iTunes How to hide UINavigationBar 1px bottom line How to fix UITableView separator on iOS 7?