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
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
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)
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:
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!
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 ...
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.