Resize UILabel based on content - ios

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!

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

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;

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;

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

Have you tried intrinsicContentSize?
myLable.numberOfLines = 0
myLable.frame = CGRect(x: 10, y: 10, width: 300, height: lblSuperscript.intrinsicContentSize().height)

Related

Set UILabel font size according to its frame size on IOS8?

I found a lot of solution with the property “adjustsFontSizeToFitWidth" , but none of these solutions works on IOS8.
I develop a responsive app and the label font size has to change according to the screen width...
I have :
label = [[UILabel alloc] init];
label.numberOfLines = 1;
label.adjustsFontSizeToFitWidth = YES;
label.font = [UIFont fontWithName:FONT_DIGITAL size:60];
[label setMinimumScaleFactor:8.0/label.font.pointSize];
label.textAlignment = NSTextAlignmentCenter;
label.frame = CGRectMake(0, 0, self.width, self.height);
label.text = #"TEXT";
[self addSubview:valueLabel];
Someone has a solution?
You should set your label's auto shrink property as shown in below image.
Hope this helps.
Following answer is a hack (not the best solution), but it works, so if you want, you can try:
- (void) sizeLabel: (UILabel *) label toRect: (CGRect) labelRect {
// Set the frame of the label to the targeted rectangle
label.frame = labelRect;
// Try all font sizes from largest to smallest font size
CGFloat fontSize = 16.0f;
CGFloat minFontSize = 5.0f;
// Fit label width wize
CGSize constraintSize = CGSizeMake(label.frame.size.width, MAXFLOAT);
do {
// Set current font size
label.font = [UIFont fontWithName:label.font.fontName size:fontSize];
// Find label size for current font size
CGRect textRect = [[label text] boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:label.font}
context:nil];
CGSize labelSize = textRect.size;
// Done, if created label is within target size
if( labelSize.height <= label.frame.size.height )
break;
// Decrease the font size and try again
fontSize -= 1.0f;
} while (fontSize > minFontSize);
}

how to adjust UITextview height based on String dynamically in ios

I have a simple textView who's data gets populated dynamically. I want to resize the height of the textview once the data is populated so that I don't see a vertical scroll nor the text gets clipped.I want to do this task programatically. I have a label which should be placed 20 px below height of textview like "interested".I am trying to making the code.But i got some problems like Alignment issues. If i can run the program the output will display like this.
this is my Program.please help me anybody.
lblHobbies = [[UILabel alloc]initWithFrame:CGRectMake(10, 310, 300, 20)];
lblHobbies.text=#"Hobbies";
lblHobbies.font=[UIFont systemFontOfSize:16.0];
lblHobbies.textColor=[UIColor colorWithRed:153.0f/255.0f green:153.0f/255.0f blue:153.0f/255.0f alpha:1];
[scrollView addSubview:lblHobbies];
lblInterests = [[UILabel alloc]initWithFrame:CGRectMake(10, 420, 300, strSize.height+30)];
lblInterests.text=#"Interests";
lblInterests.font=[UIFont systemFontOfSize:16.0];
lblInterests.textColor=[UIColor colorWithRed:153.0f/255.0f green:153.0f/255.0f blue:153.0f/255.0f alpha:1];
[scrollView addSubview:lblInterests];
NSDictionary *attributes = #{NSFontAttributeName: [UIFont systemFontOfSize:14]};
CGRect rect =
[tViewhobbies.text boundingRectWithSize:CGSizeMake(300, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
tViewhobbies=[[UITextView alloc]init];
tViewhobbies.frame=CGRectMake(10, 330,300, rect.size.height);
[tViewhobbies setUserInteractionEnabled:NO];
tViewhobbies.backgroundColor=[UIColor colorWithRed:0.662745 green:0.662745 blue:0.662745 alpha:0.5];
tViewhobbies.delegate=self;
[scrollView addSubview:tViewhobbies];
NSDictionary *attributes1 = #{NSFontAttributeName: [UIFont systemFontOfSize:14]};
CGRect rect1 =
[tViewInterests.text boundingRectWithSize:CGSizeMake(300, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes1
context:nil];
tViewInterests=[[UITextView alloc]init];
tViewInterests.frame=CGRectMake(10, 450, 300, rect1.size.height);
[tViewInterests setUserInteractionEnabled:NO];
tViewInterests.backgroundColor=[UIColor colorWithRed:0.662745 green:0.662745 blue:0.662745 alpha:0.5];
tViewInterests.delegate=self;
[scrollView addSubview:tViewInterests];
go through below code hope helps u
self.scrollView.contentSize = CGSizeMake(320, 700);
UILabel *lblHobbies = [[UILabel alloc]initWithFrame:CGRectMake(self.scrollView.bounds.origin.x + 2, self.scrollView.bounds.origin.y + 2, 75, 40)];
lblHobbies.text=#"Hobbies";
lblHobbies.font=[UIFont systemFontOfSize:16.0];
lblHobbies.textColor=[UIColor colorWithRed:153.0f/255.0f green:153.0f/255.0f blue:153.0f/255.0f alpha:1];
[self.scrollView addSubview:lblHobbies];
//add this after the hobbies textview so u need to calculate the height, so wy dont you put some helper method that returns the height for the text
//i took some long text that u want to display
NSString *str = #"BARCELONA, Spain -- Nokia is targeting emerging markets with three low-cost smartphones that use Google's Android operating system rather than the Windows Phone software from Microsoft, which is about to buy Nokia's phone business";
CGSize hobbiesTextViewSize = [self calculateHeightForString:str];
//now set the hobbiesTextView frame and also the text
UITextView *tViewhobbies = [[UITextView alloc]initWithFrame:CGRectMake(self.scrollView.bounds.origin.x + 2, self.scrollView.bounds.origin.y + 40, hobbiesTextViewSize.width, hobbiesTextViewSize.height+ 5)];
tViewhobbies.font = [UIFont systemFontOfSize:17.0f];
tViewhobbies.text = str;//set the text hear
[self.scrollView addSubview:tViewhobbies];
//now add the lblInterests label
UILabel *lblInterests = [[UILabel alloc]initWithFrame:CGRectMake(self.scrollView.bounds.origin.x + 2, self.scrollView.bounds.origin.y + lblHobbies.frame.size.height + hobbiesTextViewSize.height + 2, 75, 40)];
lblInterests.text=#"Interests";
lblInterests.font=[UIFont systemFontOfSize:16.0];
lblInterests.textColor=[UIColor colorWithRed:153.0f/255.0f green:153.0f/255.0f blue:153.0f/255.0f alpha:1];
[self.scrollView addSubview:lblInterests];
NSString *str1 = #"Nokia will ditch many of the Google services that come with Android, which Google lets phone makers customize at will. Instead, the new Nokia X line announced Monday will emphasize Microsoft services such as Bing search, Skype communications and OneDrive file storage. Its home screen sports larger, resizable tiles resembling those on Windows phone.";
//now calculate the height for Interests text
CGSize interestTextViewSize = [self calculateHeightForString:str1];
UITextView *tViewInterests = [[UITextView alloc]initWithFrame:CGRectMake(self.scrollView.bounds.origin.x + 2, self.scrollView.bounds.origin.y + lblHobbies.frame.size.height + lblInterests.frame.size.height + tViewhobbies.frame.size.height + 4, interestTextViewSize.width + 2, interestTextViewSize.height+ 2)];
tViewInterests.font = [UIFont systemFontOfSize:17.0f];
tViewInterests.text = str1;
[self.scrollView addSubview:tViewInterests];
}
//our helper method
- (CGSize)calculateHeightForString:(NSString *)str
{
CGSize size = CGSizeZero;
UIFont *labelFont = [UIFont systemFontOfSize:17.0f];
NSDictionary *systemFontAttrDict = [NSDictionary dictionaryWithObject:labelFont forKey:NSFontAttributeName];
NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:str attributes:systemFontAttrDict];
CGRect rect = [message boundingRectWithSize:(CGSize){320, MAXFLOAT}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];//you need to specify the some width, height will be calculated
size = CGSizeMake(rect.size.width, rect.size.height + 5); //padding
return size;
}
Here is how I did it:
+(CGFloat)getLabelDymanicHeightOfStringWithText:(NSString *)text andFont:(UIFont *)font andFrame:(CGRect )frame {
CGSize maxSize = CGSizeMake(frame.size.width, 999999.0);
int height = 0;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName,
nil];
if (IS_IOS_6)//iOS 6 macro
{
CGSize size = [text sizeWithFont:font
constrainedToSize:maxSize
lineBreakMode:NSLineBreakByWordWrapping];
height = size.height;
}
else
{
CGRect frame = [text boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributesDictionary
context:nil];
height = frame.size.height;
}
return height+5;
}
Pass this method your text text font and frame.
You can use custom UITextView to fix the problem:
Kindly check it out: https://github.com/HansPinckaers/GrowingTextView
Textview will set height dynamically based on input string from the user.
Hope, This will help you,
:)
enter code hereYou can use label.
myLabel.text = #"Your String";
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:CGSizeMake(320,MAX_HEIGHT_YOU_WANT_TO_SET)
lineBreakMode:NSLineBreakByWordWrapping];
CGRect frame = myLabel.frame;
frame.size.height = labelSize.height;
myLabel.frame = frame;
you can simply change the height of the textView to the height of the textView.contentSize.height. Doing this you textView will update and show all the text it contains.
textView.frame = CGRectMake(textView.frame.origin.x, textView.frame.origin.y, textView.frame.size.width,textView.contentSize.height);
Hope this helps you.
Happy Coding :)

UILabel with dynamic height into UITableviewcell

I am developing an app which required to display UILabel into UITableviewCell. I also need to resize UILabel as per text size.
I am using following code for get contentsize of text size.
CGRect rect = [as boundingRectWithSize:CGSizeMake(220.0, 2000.0) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: font} context:nil];
For update frame of UILabel I use following code.
rect.origin.x = cell.lblDescription.frame.origin.x;
rect.origin.y = cell.lblDescription.frame.origin.y;
rect.size.width = cell.lblDescription.frame.size.width;
[cell.lblDescription setFrame:rect];
It set wrong frame.
Please find attached screenshot.
NSString *text = [NSString stringWithFormat:#"%#",[[arr_cart objectAtIndex:indexPath.row] objectForKey:#"name"]];
UIFont *font = [UIFont fontWithName:#"ArialMT" size:12];
CGSize size = [(text ? text : #"") sizeWithFont:font constrainedToSize:CGSizeMake(200, 9999) lineBreakMode:NSLineBreakByWordWrapping];
UILabel *lbl_desc=[[UILabel alloc]init];
lbl_desc.numberOfLines = 0;
lbl_desc.frame=CGRectMake(70,18, size.width, size.height);
lbl_desc.lineBreakMode = NSLineBreakByWordWrapping;
lbl_desc.text = (text ? text : #"");
lbl_desc.font = font;
lbl_desc.backgroundColor=[UIColor clearColor];
lbl_desc.textColor = [UIColor darkTextColor];
[cell.contentView addSubview:lbl_desc];
[lbl_desc release];
You have to check the height of the label in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath UITableViewDelegate Method.
CGSize maximumLabelSize = CGSizeMake(your_label_width, FLT_MAX);
CGSize expectedLabelSize = [label_text sizeWithFont:[UIFont fontWithName:#"your_font" size:your_font_size] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];
then set the cell height as expectedLabelSize.height.
also do the same thing in your custom cell.
Use following code
[self setDynamicHeightOfLabel:lblName withLblWidth:97 andFontSize:13];
In above method you just need to pass your UILabel name with specific width and fontSize of label.
-(void) setDynamicHeightOfLabel:(UILabel *) myLabel withLblWidth:(CGFloat) width andFontSize:(int) fontSize
{
CGSize myLabelSize = CGSizeMake(width, FLT_MAX);
CGSize expecteingmyLabelSize = [myLabel.text sizeWithFont:myLabel.font constrainedToSize:myLabelSize lineBreakMode:myLabel.lineBreakMode];
CGRect lblFrame = myLabel.frame;
lblFrame.size.height = expecteingmyLabelSize.height;
myLabel.frame = lblFrame;
int addressLine = myLabel.frame.size.height/fontSize;
myLabel.numberOfLines = addressLine;
}
Using above code you can set dynamic height of UILabel.

How to resize and transform labels?

My application requires the user to enter few details which are then displayed via another view by using labels.
As the user can enter variable length of text, while the label initially had a fixed length and breadth, I used a code like the following to adjust the label size:
CGSize maximumLabelSize = CGSizeMake(296,9999);
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;
The problem with these modifications is that I have many labels one after the other. So when I change the length of one label, all the following labels also need to be transformed/moved to new locations.
Is there any way that I can change the size and location of all labels dynamically, while ensuring that the final presentation is as good as it was in case of fixed length labels?
int h=10; // Initial Height as you want
for(int k=0;k<[headItemArray count];k++) {
CGSize size_txt_overview1 = [[headItemArray objectAtIndex:k] sizeWithFont:[UIFont fontWithName:#"Helvetica" size:18] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
UILabel *lbl_headitem = [[UILabel alloc]initWithFrame:CGRectMake(3,h, 690, size_txt_overview1.height)];// See the 'h' value
lbl_headitem.text = [headItemArray objectAtIndex:k];
[lbl_headitem setTextAlignment:UITextAlignmentLeft];
[lbl_headitem setBackgroundColor:[UIColor clearColor]];
[lbl_headitem setTag:k];
lbl_headitem.numberOfLines=0;
[lbl_headitem setTextColor:[UIColor redColor]];
[lbl_headitem setFont:[UIFont fontWithName:#"Helvetica" size:18]];
[scrollAttributes addSubview:lbl_headitem];
h = h + size_txt_overview1.height;// important
}

How to calculate UILabel width based on text length?

I want to display an image next to a UILabel, however UILabel has variable text length, so I don't know where to place the image. How can I accomplish this?
CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font
constrainedToSize:maximumLabelSize
lineBreakMode:yourLabel.lineBreakMode];
What is -[NSString sizeWithFont:forWidth:lineBreakMode:] good for?
this question might have your answer, it worked for me.
For 2014, I edited in this new version, based on the ultra-handy comment by Norbert below! This does everything.
// yourLabel is your UILabel.
float widthIs =
[self.yourLabel.text
boundingRectWithSize:self.yourLabel.frame.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName:self.yourLabel.font }
context:nil]
.size.width;
NSLog(#"the width of yourLabel is %f", widthIs);
yourLabel.intrinsicContentSize.width for Objective-C / Swift
In swift
yourLabel.intrinsicContentSize().width
The selected answer is correct for iOS 6 and below.
In iOS 7, sizeWithFont:constrainedToSize:lineBreakMode: has been deprecated. It is now recommended you use boundingRectWithSize:options:attributes:context:.
CGRect expectedLabelSize = [yourString boundingRectWithSize:sizeOfRect
options:<NSStringDrawingOptions>
attributes:#{
NSFontAttributeName: yourString.font
AnyOtherAttributes: valuesForAttributes
}
context:(NSStringDrawingContext *)];
Note that the return value is a CGRect not a CGSize. Hopefully that'll be of some assistance to people using it in iOS 7.
Swift 4 Answer who are using Constraint
label.text = "Hello World"
var rect: CGRect = label.frame //get frame of label
rect.size = (label.text?.size(attributes: [NSFontAttributeName: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))! //Calculate as per label font
labelWidth.constant = rect.width // set width to Constraint outlet
Swift 5 Answer who are using Constraint
label.text = "Hello World"
var rect: CGRect = label.frame //get frame of label
rect.size = (label.text?.size(withAttributes: [NSAttributedString.Key.font: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))! //Calculate as per label font
labelWidth.constant = rect.width // set width to Constraint outlet
In iOS8 sizeWithFont has been deprecated, please refer to
CGSize yourLabelSize = [yourLabel.text sizeWithAttributes:#{NSFontAttributeName : [UIFont fontWithName:yourLabel.font size:yourLabel.fontSize]}];
You can add all the attributes you want in sizeWithAttributes.
Other attributes you can set:
- NSForegroundColorAttributeName
- NSParagraphStyleAttributeName
- NSBackgroundColorAttributeName
- NSShadowAttributeName
and so on. But probably you won't need the others
CGRect rect = label.frame;
rect.size = [label.text sizeWithAttributes:#{NSFontAttributeName : [UIFont fontWithName:label.font.fontName size:label.font.pointSize]}];
label.frame = rect;
Here's something I came up with after applying a few principles other SO posts, including Aaron's link:
AnnotationPin *myAnnotation = (AnnotationPin *)annotation;
self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
self.backgroundColor = [UIColor greenColor];
self.frame = CGRectMake(0,0,30,30);
imageView = [[UIImageView alloc] initWithImage:myAnnotation.THEIMAGE];
imageView.frame = CGRectMake(3,3,20,20);
imageView.layer.masksToBounds = NO;
[self addSubview:imageView];
[imageView release];
CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]];
CGRect newFrame = self.frame;
newFrame.size.height = titleSize.height + 12;
newFrame.size.width = titleSize.width + 32;
self.frame = newFrame;
self.layer.borderColor = [UIColor colorWithRed:0 green:.3 blue:0 alpha:1.0f].CGColor;
self.layer.borderWidth = 3.0;
UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(26,5,newFrame.size.width-32,newFrame.size.height-12)];
infoLabel.text = myAnnotation.title;
infoLabel.backgroundColor = [UIColor clearColor];
infoLabel.textColor = [UIColor blackColor];
infoLabel.textAlignment = UITextAlignmentCenter;
infoLabel.font = [UIFont systemFontOfSize:12];
[self addSubview:infoLabel];
[infoLabel release];
In this example, I'm adding a custom pin to a MKAnnotation class that resizes a UILabel according to the text size. It also adds an image on the left side of the view, so you see some of the code managing the proper spacing to handle the image and padding.
The key is to use CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]]; and then redefine the view's dimensions. You can apply this logic to any view.
Although Aaron's answer works for some, it didn't work for me. This is a far more detailed explanation that you should try immediately before going anywhere else if you want a more dynamic view with an image and resizable UILabel. I already did all the work for you!!

Resources