Resize UILabel based on content
Asked Answered
A

6

7

I have a UILabel, his text size has the property

title.adjustsFontSizeToFitWidth = YES;

that prevents me from using standard methods to resize the UILabel. I read on another post here that I'm supposed to use the function

sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode

from this answer: How to figure out the font size of a UILabel when -adjustsFontSizeToFitWidth is set to YES?

Now, i can't figure out how to make it work.. this is the actual code

UIFont *font = [UIFont fontWithName:@"Marker Felt" size:200];
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, width, 20.0)];
title.text = @"this is a long title that should be resized";
title.font = font;
title.numberOfLines = 1;
title.adjustsFontSizeToFitWidth = YES;

CGFloat pointSize = 0.0;
CGSize size = [title.text sizeWithFont:font 
                           minFontSize:title.minimumFontSize 
                        actualFontSize:&pointSize 
                              forWidth:width 
                         lineBreakMode:title.lineBreakMode];
title.frame = CGRectMake(title.frame.origin.x, 
                         title.frame.origin.y, 
                         size.width, 
                         size.height);

The UILabel get resized wrongly, as if the font size it's still 200.. Any clues? Thanks!

Aboral answered 30/8, 2011 at 11:44 Comment(6)
What is title.minimumFontSize? What value is in width variable?Bagnio
there is no minimumFontSize set for now, and width is just the width of the UIView I want this text in (let's suppose it's 200.0)Aboral
try to set it to 10, for example =) If you have fixed width then what do you want to get from size? height?Bagnio
Yes I'm trying to get the height.. Basically the point is to simulate a vertical top text aligment that uilabel doesn't supportAboral
Did you try to set title.minimumFontSize to something lower then 200?Bagnio
Try to use code from my answer.Bagnio
Y
6

I'd suggest filing this as a bug.

The size returned by -sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: has the correct width, but not the height does not account for the actual font size.

It seems likely that UILabel also has this bug. Changing the size of a label to match the height of the text in a font of the size returned by -sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: will incorrectly vertically position the text within the label.

A work-around is to calculate the correct height, and change the font on the label to with the actual font size:

CGFloat pointSize = 0.0f;
CGRect frame = title.frame;
frame.size = [title.text sizeWithFont:font
                          minFontSize:title.minimumFontSize
                       actualFontSize:&pointSize
                             forWidth:width
                        lineBreakMode:title.lineBreakMode];
UIFont *actualFont = [UIFont fontWithName:@"Marker Felt" size:pointSize];
CGSize sizeWithCorrectHeight = [title.text sizeWithFont:actualFont];
frame.size.height = sizeWithCorrectHeight.height;
title.frame = frame;
title.font = actualFont;
Yaw answered 30/8, 2011 at 12:56 Comment(1)
sizeWithFont is deprecatedDiplomacy
I
8

I have some code you could use on my github, check it out, it's a category for UILabel, you need to set the frame width and when you can resizeToFit on the UILabel, it adjusts the height to fit the content, and returns the y position of the end of the label so you can adjust any content appearing after it.

https://gist.github.com/1005520

Irishirishism answered 30/8, 2011 at 12:16 Comment(3)
Tried to use it but I'm not sure.. The thing is i set frame width, I call resizeToFit and it gets resized, but the font size is still 200 (so the text gets wrapped on multiple lines)... My point is to get just one line of text that fills the view (with the font-size changing based on how long is the string).. Is this possible with your code?Aboral
No, my code was for multiline labels, setting the frame to have height 0 for example, you would provide the text and the code handles resizing the height. Maybe not what you're looking for in this case. Sorry...Irishirishism
added gist last comment to my tool filePapyrology
Y
6

I'd suggest filing this as a bug.

The size returned by -sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: has the correct width, but not the height does not account for the actual font size.

It seems likely that UILabel also has this bug. Changing the size of a label to match the height of the text in a font of the size returned by -sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: will incorrectly vertically position the text within the label.

A work-around is to calculate the correct height, and change the font on the label to with the actual font size:

CGFloat pointSize = 0.0f;
CGRect frame = title.frame;
frame.size = [title.text sizeWithFont:font
                          minFontSize:title.minimumFontSize
                       actualFontSize:&pointSize
                             forWidth:width
                        lineBreakMode:title.lineBreakMode];
UIFont *actualFont = [UIFont fontWithName:@"Marker Felt" size:pointSize];
CGSize sizeWithCorrectHeight = [title.text sizeWithFont:actualFont];
frame.size.height = sizeWithCorrectHeight.height;
title.frame = frame;
title.font = actualFont;
Yaw answered 30/8, 2011 at 12:56 Comment(1)
sizeWithFont is deprecatedDiplomacy
B
2

Try to create font with smaller fontSize. For example:

UIFont *font = [UIFont fontWithName:@"Marker Felt" size:20];

but to actualFontSize pass link to CGFloat == 200.

UPDATED:

try this then:

UIFont *font = [UIFont fontWithName:@"Marker Felt" size:20];
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, width, 20.0)];
title.text = @"this is a long title that should be resized";
title.font = font;
title.numberOfLines = 1;
title.adjustsFontSizeToFitWidth = YES;

CGFloat pointSize = 0.0;
CGSize size = [title.text sizeWithFont:font minFontSize:title.minimumFontSize actualFontSize:&pointSize forWidth:width lineBreakMode:title.lineBreakMode];
title.frame = CGRectMake(title.frame.origin.x, title.frame.origin.y, size.width, size.height);
font = [UIFont fontWithName:@"Marker Felt" size:200];
title.font = font;
Bagnio answered 30/8, 2011 at 12:30 Comment(3)
this way the text stays 20pts! adjustsFontSizeToFitWidth works by downscaling only AFAIK. also actualfontsize is not read, just set!Aboral
Updated my answer. Try it, pls. Replace 20 with your minimum font sizeBagnio
this is kinda working for specific cases... when the frame created by a font size 20 is enough! I'm gonna post the solution I found, thanks for your help anyways! edit: not gonna post it, really similar to the one posted by lemnar :pAboral
C
0
UILabel * label = [[UILabel alloc] init];
        [label setNumberOfLines:0];
        label.text=[detailDict valueForKey:@"method"];
        [label setFont:[UIFont fontWithName:@"Georgia" size:16.0]];
        CGSize labelsize=[label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(250, 1000.0) lineBreakMode:UILineBreakModeWordWrap];
        int y=0;
        label.frame=CGRectMake(38, y, 245, labelsize.height);
        [label setBackgroundColor:[UIColor clearColor]];
        [label setTextColor:[UIColor whiteColor]];
        scrollView.showsVerticalScrollIndicator = NO;
        y+=labelsize.height;
        [scrollView setContentSize:CGSizeMake(200,y+50)];
        [scrollView addSubview:label];
        [label release];

I think you should use this code and i am using the label on scrollview for a big text you can also do so

Cece answered 30/8, 2011 at 12:8 Comment(1)
Can you please explain more on how this is supposed to work with adjustsFontSizeToFitWidth? thanks!Aboral
D
0

Have you tried intrinsicContentSize?

    myLable.numberOfLines = 0
    myLable.frame = CGRect(x: 10, y: 10, width: 300, height: lblSuperscript.intrinsicContentSize().height)
Davy answered 29/12, 2015 at 7:8 Comment(0)
O
0

this code worked for me

    questionLabel.numberOfLines = 0
    questionLabel.sizeToFit()
    questionLabel.layoutIfNeeded()
Ownership answered 26/6, 2023 at 7:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.