How to calculate the Width and Height of NSString on UILabel - objective-c

I am working on a project to make the NSString on UILabel Width and Height dynamically.
I tried with:
NSString *text = [messageInfo objectForKey:#"compiled"];
writerNameLabel.numberOfLines = 0;
writerNameLabel.textAlignment = UITextAlignmentRight;
writerNameLabel.backgroundColor = [UIColor clearColor];
CGSize constraint = CGSizeMake(296,9999);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
NSLog(#"sizewidth = %f, sizeheight = %f", size.width, size.height);
NSLog(#"writerNameLabel.frame.size.width 1 -> %f",writerNameLabel.frame.size.width);
[writerNameLabel setFrame:CGRectMake(writerNameLabel.frame.origin.x, writerNameLabel.frame.origin.y, size.width, size.height)];
CGRect labelFram = writerNameLabel.frame;
labelFram.origin.x = cell.frame.size.width - writerNameLabel.frame.size.width - 80;
writerNameLabel.frame = labelFram;
NSLog(#"writerNameLabel.frame.size.width 2-> %f",writerNameLabel.frame.size.width);
Please see the green bubble not the grey one.
Still not right.
The code for bubble
bubbleImageView.frame = CGRectMake(writerNameLabel.frame.origin.x, writerNameLabel.frame.origin.y, writerNameLabel.frame.size.width+15, writerNameLabel.frame.size.height+5);
Please Advise! Thanks!

That's because you did not reuse the table cell, the structure should be like:
NSString *text = [messageInfo objectForKey:#"compiled"];
if(cell == nil)
{
writerNameLabel.numberOfLines = 0;
writerNameLabel.textAlignment = UITextAlignmentRight;
writerNameLabel.backgroundColor = [UIColor clearColor];
[cell addSubview:writerNameLabel];
}
else {
writerNameLabel = (UILabel *)[cell viewWithTag:WRITER_NAME_LABEL_TAG];
}
CGSize constraint = CGSizeMake(296,9999);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
[writerNameLabel setFrame:CGRectMake(writerNameLabel.frame.origin.x, writerNameLabel.frame.origin.y, size.width, size.height)];
I've been gone through and answered some of your question, that's correct way to write your tableview controller. And your problem will be solved.

Related

Dynamic collection view cell size-objective c?

I am working on collection view in objective c,
My problem was
1.I want to change the cell size according to it's content size
2.If there are no image in cell then like and comment view should go above(refer image).
I have changed the constraint like
NSLayoutConstraint *newConstraint;
if([image isEqualToString:#"no_image.jpg"] || [image isEqualToString:#"no_image.jpg"]){
cell.desc_ImgViewWidth.constant = 0;
[cell.Descimgview setHidden:YES];
newConstraint = [NSLayoutConstraint constraintWithItem:(cell.bottomConstraint).firstItem attribute:(cell.bottomConstraint).firstAttribute relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:(cell.bottomConstraint).secondItem attribute:(cell.bottomConstraint).secondAttribute multiplier:(cell.bottomConstraint).multiplier constant:(cell.bottomConstraint).constant];
}
else{
cell.desc_ImgViewWidth.constant = 120;
[cell.Descimgview setHidden:NO];
newConstraint = [NSLayoutConstraint constraintWithItem:(cell.bottomConstraint).firstItem attribute:(cell.bottomConstraint).firstAttribute relatedBy:NSLayoutRelationEqual toItem:(cell.bottomConstraint).secondItem attribute:(cell.bottomConstraint).secondAttribute multiplier:(cell.bottomConstraint).multiplier constant:(cell.bottomConstraint).constant];
}
[cell.contentView removeConstraint:(cell.bottomConstraint)];
[cell.contentView addConstraint:newConstraint];
[cell layoutIfNeeded];
[[cell contentView] setFrame:[cell bounds]];
[[cell contentView] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
in cellForItemAtIndexPath delegate method.(like and comment view moving above at first, but after reloading the cell again i.e, like scrolling etc the constraint is not working perfectly)
I want to move like and comment view like this and to reduce the cell height for that particular cell(refer below image)
How to properly do this?
You can use UICollectionViewLayout
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
if imageView != nil
{
return CGSizeMake(width, height)
}
else
{
return CGSizeMake(width, height)
}
}
Finally achieved like this,
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary* object = [_Data objectAtIndex:indexPath.item];
NSString *image = [object valueForKey:#"image"];
if([image isEqualToString:#"no_image.jpg"] || [image isEqualToString:#"no_image.jpg"]){
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
float cellWidth = screenWidth;
NSDictionary* object = [_Data objectAtIndex:indexPath.item];
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:[SwiftHelper getEmojiText:[object valueForKey:#"description"]]];
[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Georgia" size:15.0] range:NSMakeRange(0, str.length)];
CGSize sizeName = CGRectIntegral([str boundingRectWithSize:CGSizeMake(cellWidth-8, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil]).size;
NSMutableAttributedString *str1 = [[NSMutableAttributedString alloc] initWithString:[SwiftHelper getEmojiText:[object valueForKey:#"name"]]];
[str1 addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"Georgia" size:15.0] range:NSMakeRange(0, str1.length)];
CGSize sizeName1 = CGRectIntegral([str1 boundingRectWithSize:CGSizeMake(cellWidth-8, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil]).size;
NSLog(#"%f,%f",sizeName.height,sizeName1.height);
if(sizeName.height > 100){
sizeName.height = 70;
}
return CGSizeMake(cellWidth, sizeName.height + sizeName1.height + 110);
}
else{
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
float cellWidth = screenWidth;
CGSize size = CGSizeMake(cellWidth, 182);
return size;
}
Thank you for your suggestions friends.
Really it's better to use tableview for this but unfortunately after using collection view for a previous design the requirement changed like this. So, I struggled.

Objective c label.numberOflines is not working [duplicate]

Consider I have the following text in a UILabel (a long line of dynamic text):
Since the alien army vastly outnumbers the team, players must use the post-apocalyptic world to their advantage, such as seeking cover behind dumpsters, pillars, cars, rubble, and other objects.
I want to resize the UILabel's height so that the text can fit in. I'm using following properties of UILabel to make the text within to wrap.
myUILabel.lineBreakMode = UILineBreakModeWordWrap;
myUILabel.numberOfLines = 0;
Please let me know if I'm not heading in the right direction. Thanks.
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;
You were going in the right direction. All you need to do is:
myUILabel.numberOfLines = 0;
myUILabel.text = #"Enter large amount of text here";
[myUILabel sizeToFit];
In iOS 6 Apple has added a property to UILabel that greatly simplifies dynamic vertical resizing of labels: preferredMaxLayoutWidth.
Using this property in combination with lineBreakMode = NSLineBreakByWordWrapping and sizeToFit method allows easily resize a UILabel instance to the height that accommodates the entire text.
A quote from iOS documentation:
preferredMaxLayoutWidth
The preferred maximum width (in points) for a multiline label.
Discussion
This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text is flowed to one or more new lines, thereby increasing the height of the label.
A sample:
...
UILabel *status = [[UILabel alloc] init];
status.lineBreakMode = NSLineBreakByWordWrapping;
status.numberOfLines = 5; // limits to 5 lines; use 0 for unlimited.
[self addSubview:status]; // self here is the parent view
status.preferredMaxLayoutWidth = self.frame.size.width; // assumes the parent view has its frame already set.
status.text = #"Some quite lengthy message may go here…";
[status sizeToFit];
[status setNeedsDisplay];
...
Check this work perfectly without adding Single line of code. (Using Autolayout)
I made a demo for you according to your requirement. Download it from below link,
Autoresize UIView and UILabel
Step by Step Guide :-
Step 1 :- Set constrain to UIView
1) Leading 2) Top 3) Trailing (From mainview)
Step 2 :- Set constrain to Label 1
1) Leading 2) Top 3) Trailing (From it's superview)
Step 3 :- Set constrain to Label 2
1) Leading 2) Trailing (From it's superview)
Step 4 :- Most tricky give botton to UILabel from UIView .
Step 5 :- (Optional) Set constrain to UIButton
1) Leading 2) Bottom 3) Trailing 4) Fixed Height (From mainview)
Output :-
Note :- Make sure you have set Number of lines =0 in Label property.
I hope this info enough to understand Autoresize UIView according to UILabel's height and Autoresize UILabel According to text.
Instead doing this programmatically, you can do this in Storyboard/XIB while designing.
Set UIlabel's number of lines property to 0 in attribute inspector.
Then set width constraint/(or) leading and trailing constraint as per the requirement.
Then set height constraint with minimum value. Finally select the height constraint you added and in the size inspector the one next to attribute inspector, change the height constraint's relation from equal to - greater than.
Thanks guys for help, here is the code I tried which is working for me
UILabel *instructions = [[UILabel alloc]initWithFrame:CGRectMake(10, 225, 300, 180)];
NSString *text = #"First take clear picture and then try to zoom in to fit the ";
instructions.text = text;
instructions.textAlignment = UITextAlignmentCenter;
instructions.lineBreakMode = NSLineBreakByWordWrapping;
[instructions setTextColor:[UIColor grayColor]];
CGSize expectedLabelSize = [text sizeWithFont:instructions.font
constrainedToSize:instructions.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGRect newFrame = instructions.frame;
newFrame.size.height = expectedLabelSize.height;
instructions.frame = newFrame;
instructions.numberOfLines = 0;
[instructions sizeToFit];
[self addSubview:instructions];
Solution to iOS7 prior and iOS7 above
//
// UILabel+DynamicHeight.m
// For StackOverFlow
//
// Created by Vijay on 24/02/14.
// Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//
#import <UIKit/UIKit.h>
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define iOS7_0 #"7.0"
#interface UILabel (DynamicHeight)
/*====================================================================*/
/* Calculate the size,bounds,frame of the Multi line Label */
/*====================================================================*/
/**
* Returns the size of the Label
*
* #param aLabel To be used to calculte the height
*
* #return size of the Label
*/
-(CGSize)sizeOfMultiLineLabel;
#end
//
// UILabel+DynamicHeight.m
// For StackOverFlow
//
// Created by Vijay on 24/02/14.
// Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//
#import "UILabel+DynamicHeight.h"
#implementation UILabel (DynamicHeight)
/*====================================================================*/
/* Calculate the size,bounds,frame of the Multi line Label */
/*====================================================================*/
/**
* Returns the size of the Label
*
* #param aLabel To be used to calculte the height
*
* #return size of the Label
*/
-(CGSize)sizeOfMultiLineLabel{
NSAssert(self, #"UILabel was nil");
//Label text
NSString *aLabelTextString = [self text];
//Label font
UIFont *aLabelFont = [self font];
//Width of the Label
CGFloat aLabelSizeWidth = self.frame.size.width;
if (SYSTEM_VERSION_LESS_THAN(iOS7_0)) {
//version < 7.0
return [aLabelTextString sizeWithFont:aLabelFont
constrainedToSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
lineBreakMode:NSLineBreakByWordWrapping];
}
else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(iOS7_0)) {
//version >= 7.0
//Return the calculated size of the Label
return [aLabelTextString boundingRectWithSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{
NSFontAttributeName : aLabelFont
}
context:nil].size;
}
return [self bounds].size;
}
#end
Since sizeWithFont is deprecated I use this one instead.
this one get label specific attributes.
-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text{
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:#{NSFontAttributeName:label.font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){label.frame.size.width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
return ceil(rect.size.height);
}
UILabel extension based on this answer for Swift 4 and above
extension UILabel {
func retrieveTextHeight () -> CGFloat {
let attributedText = NSAttributedString(string: self.text!, attributes: [NSFontAttributeName:self.font])
let rect = attributedText.boundingRect(with: CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)
return ceil(rect.size.height)
}
}
Can be used like:
self.labelHeightConstraint.constant = self.label.retrieveTextHeight()
Here is a category version:
UILabel+AutoSize.h
#import
#interface UILabel (AutoSize)
- (void) autosizeForWidth: (int) width;
#end
UILabel+AutoSize.m
#import "UILabel+AutoSize.h"
#implementation UILabel (AutoSize)
- (void) autosizeForWidth: (int) width {
self.lineBreakMode = UILineBreakModeWordWrap;
self.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(width, FLT_MAX);
CGSize expectedLabelSize = [self.text sizeWithFont:self.font constrainedToSize:maximumLabelSize lineBreakMode:self.lineBreakMode];
CGRect newFrame = self.frame;
newFrame.size.height = expectedLabelSize.height;
self.frame = newFrame;
}
#end
You can implement TableViewController's (UITableViewCell *)tableView:cellForRowAtIndexPath method in the following way (for example) :
#define CELL_LABEL_TAG 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = #"my long text";
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:identifier] autorelease];
}
CGFloat width = [UIScreen mainScreen].bounds.size.width - 50;
CGFloat height = [self textHeight:text] + 10;
CGRect frame = CGRectMake(10.0f, 10.0f, width, height);
UILabel *cellLabel = [[UILabel alloc] initWithFrame:frame];
cellLabel.tag = CELL_LABEL_TAG;
cellLabel.textColor = [UIColor blackColor];
cellLabel.backgroundColor = [UIColor clearColor];
cellLabel.textAlignment = UITextAlignmentLeft;
cellLabel.font = [UIFont systemFontOfSize:12.0f];
[cell.contentView addSubview:cellLabel];
[cellLabel release];
return cell;
}
UILabel *label = (UILabel *)[cell viewWithTag:CELL_LABEL_TAG];
label.text = text;
label.numberOfLines = 0;
[label sizeToFit];
return cell;
Also use NSString's sizeWithFont:constrainedToSize:lineBreakMode: method to compute the text's height.
My approach to compute the dynamic height of UILabel.
let width = ... //< width of this label
let text = ... //< display content
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.preferredMaxLayoutWidth = width
// Font of this label.
//label.font = UIFont.systemFont(ofSize: 17.0)
// Compute intrinsicContentSize based on font, and preferredMaxLayoutWidth
label.invalidateIntrinsicContentSize()
// Destination height
let height = label.intrinsicContentSize.height
Wrap to function:
func computeHeight(text: String, width: CGFloat) -> CGFloat {
// A dummy label in order to compute dynamic height.
let label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.font = UIFont.systemFont(ofSize: 17.0)
label.preferredMaxLayoutWidth = width
label.text = text
label.invalidateIntrinsicContentSize()
let height = label.intrinsicContentSize.height
return height
}
And for those that are migrating to iOS 8, here is a class extension for Swift:
extension UILabel {
func autoresize() {
if let textNSString: NSString = self.text {
let rect = textNSString.boundingRectWithSize(CGSizeMake(self.frame.size.width, CGFloat.max),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: self.font],
context: nil)
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, rect.height)
}
}
}
The easiest and better way that worked for me was to apply height constraint to label and set the priority to low, i.e., (250) in storyboard.
So you need not worry about calculating the height and width programmatically, thanks to storyboard.
Updated Method
+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {
CGSize constraint = CGSizeMake(width, 20000.0f);
CGSize size;
CGSize boundingBox = [text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:font}
context:nil].size;
size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
return size.height;
}
This is one line of code to get the UILabel Height using Objective-c:
labelObj.numberOfLines = 0;
CGSize neededSize = [labelObj sizeThatFits:CGSizeMake(screenWidth, CGFLOAT_MAX)];
and using .height you will get the height of label as follows:
neededSize.height
You can get height using below code
You have to pass
text 2. font 3. label width
func heightForLabel(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
}
Thanks for this post. It helped me a great deal. In my case I am also editing the text in a separate view controller. I noticed that when I use:
[cell.contentView addSubview:cellLabel];
in the tableView:cellForRowAtIndexPath: method that the label view was continually rendered over the top of the previous view each time I edited the cell. The text became pixelated, and when something was deleted or changed, the previous version was visible under the new version. Here's how I solved the problem:
if ([[cell.contentView subviews] count] > 0) {
UIView *test = [[cell.contentView subviews] objectAtIndex:0];
[test removeFromSuperview];
}
[cell.contentView insertSubview:cellLabel atIndex:0];
No more weird layering. If there is a better way to handle this, Please let me know.
UILabel *itemTitle = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10,100, 200.0f)];
itemTitle.text = #"aseruy56uiytitfesh";
itemTitle.adjustsFontSizeToFitWidth = NO;
itemTitle.autoresizingMask = UIViewAutoresizingFlexibleWidth;
itemTitle.font = [UIFont boldSystemFontOfSize:18.0];
itemTitle.textColor = [UIColor blackColor];
itemTitle.shadowColor = [UIColor whiteColor];
itemTitle.shadowOffset = CGSizeMake(0, 1);
itemTitle.backgroundColor = [UIColor blueColor];
itemTitle.lineBreakMode = UILineBreakModeWordWrap;
itemTitle.numberOfLines = 0;
[itemTitle sizeToFit];
[self.view addSubview:itemTitle];
use this here all the properties are used on the label and test it by increasing the text in the itemTitle.text as
itemTitle.text = #"diofgorigjveghnhkvjteinughntivugenvitugnvkejrfgnvkhv";
it will show the perfetc answer as you need
You may use it as a method, as well. #Pyjamasam is very much true so i am just making its method. It may be helpfull for some one else
-(CGRect)setDynamicHeightForLabel:(UILabel*)_lbl andMaxWidth:(float)_width{
CGSize maximumLabelSize = CGSizeMake(_width, FLT_MAX);
CGSize expectedLabelSize = [_lbl.text sizeWithFont:_lbl.font constrainedToSize:maximumLabelSize lineBreakMode:_lbl.lineBreakMode];
//adjust the label the the new height.
CGRect newFrame = _lbl.frame;
newFrame.size.height = expectedLabelSize.height;
return newFrame;
}
and just set it like this
label.frame = [self setDynamicHeightForLabel:label andMaxWidth:300.0];
To do this in Swift3 following is the code:
let labelSizeWithFixedWith = CGSize(width: 300, height: CGFloat.greatestFiniteMagnitude)
let exactLabelsize = self.label.sizeThatFits(labelSizeWithFixedWith)
self.label.frame = CGRect(origin: CGPoint(x: 20, y: 20), size: exactLabelsize)
Adding to the above answers:
This can be easily achieved via storyboard.
Set constraint for UILabel.(In my case I did top, left and fixed width)
Set Number of line to 0 in Attribute Inspector
Set Line Break to WordWrap in Attribute Inspector.
One line is Chris's answer is wrong.
newFrame.size.height = maximumLabelSize.height;
should be
newFrame.size.height = expectedLabelSize.height;
Other than that, it's the correct solution.
Finally, it worked. Thank you guys.
I was not getting it to work because i was trying to resize the label in heightForRowAtIndexPath method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
and (yeah silly me), i was resizing the label to default in cellForRowAtIndexPath method - i was overlooking the code i had written earlier:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cellIdentifier = #"myCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
cell.myUILabel.lineBreakMode = UILineBreakModeWordWrap;
cell.myUILabel.numberOfLines = 0;
cell.myUILabel.text = #"Some very very very very long text....."
[cell.myUILabel.criterionDescriptionLabel sizeToFit];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
CGFloat rowHeight = cell.myUILabel.frame.size.height + 10;
return rowHeight;
}
NSString *str = #"Please enter your text......";
CGSize lblSize = [str sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize: CGSizeMake(200.0f, 600.0f) lineBreakMode: NSLineBreakByWordWrapping];
UILabel *label = [[UILabel alloc]init];
label.frame = CGRectMake(60, 20, 200, lblSize.height);
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.font = [UIFont systemFontOfSize:15];
label.text = str;
label.backgroundColor = [UIColor clearColor];
[label sizeToFit];
[self.view addSubview:label];
My code:
UILabel *label = [[UILabel alloc] init];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = text;
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont fontWithName:_bodyTextFontFamily size:_bodyFontSize];
CGSize size = [label sizeThatFits:CGSizeMake(width, MAXFLOAT)];
float height = size.height;
label.frame = CGRectMake(x, y, width, height);
This method will give perfect height
-(float) getHeightForText:(NSString*) text withFont:(UIFont*) font andWidth:(float) width{
CGSize constraint = CGSizeMake(width , 20000.0f);
CGSize title_size;
float totalHeight;
title_size = [text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName : font }
context:nil].size;
totalHeight = ceil(title_size.height);
CGFloat height = MAX(totalHeight, 40.0f);
return height;
}
Swift 2:
yourLabel.text = "your very long text"
yourLabel.numberOfLines = 0
yourLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
yourLabel.frame.size.width = 200
yourLabel.frame.size.height = CGFloat(MAXFLOAT)
yourLabel.sizeToFit()
The interesting lines are sizeToFit() in conjunction with setting a frame.size.height to the max float, this will give room for long text, but sizeToFit() will force it to only use the necessary, but ALWAYS call it after setting the .frame.size.height .
I recommend setting a .backgroundColor for debug purposes, this way you can see the frame being rendered for each case.
myLabel.text = "your very long text"
myLabel.numberOfLines = 0
myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
Please set constraints for UILable in storyboard including top left bottom right

Change the height of UILabel dynamically based on content

I have a UILabel as subview of UIButton and I am passing the value
from another view and populating in UILabel. Now, I want that UILabel
must change its height based on the content.If text is "Hello" it must
be in 1 line but if text is " my text is too long to fit in the
label", it must change its size. I have used
[self.addressLabel sizeToFit];
But for this i need to leave empty space below UILabel. Simply what I
want is that when text strength increases,size of UILabel and UIView
must expand.
Using below you can get the height of the label
text - text of the label
font - font used in label
width - width of the label
-(float) getHeightForText:(NSString*) text withFont:(UIFont*) font andWidth:(float) width{
CGSize constraint = CGSizeMake(width , 20000.0f);
CGSize title_size;
float totalHeight;
SEL selector = #selector(boundingRectWithSize:options:attributes:context:);
if ([text respondsToSelector:selector]) {
title_size = [text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName : font }
context:nil].size;
totalHeight = ceil(title_size.height);
} else {
title_size = [text sizeWithFont:font
constrainedToSize:constraint
lineBreakMode:NSLineBreakByWordWrapping];
totalHeight = title_size.height ;
}
CGFloat height = MAX(totalHeight, 40.0f);
return height;
}
and create a frame using the height
CGRect frame = questionTitleLbl.frame;
float height = [self getHeightForText:questionTitleLbl.text
withFont:questionTitleLbl.font
andWidth:questionTitleLbl.frame.size.width];
float gap = 2;
cell.questionTitleLbl.frame = CGRectMake(frame.origin.x,
frame.origin.y,
frame.size.width,
height);
Here is the way that i handle this issue:
UILabel *sight = (UILabel *)[cell viewWithTag:100];
sight.text=tmpGroup.title;
sight.frame =CGRectMake(sight.frame.origin.x, sight.frame.origin.y, 191, 21);
sight.font = [UIFont fontWithName:#"RobotoSlab-Bold" size:10];
sight.numberOfLines=0;
sight.lineBreakMode=NSLineBreakByWordWrapping;
[sight sizeToFit];
Use this code its very easy and updated with ios8
add this method to your appconstant file
inline static CGSize getLabelHeightForFont(NSString *fontName,NSString* str, float fontSize, float lblWidth)
{
NSString *text = str;
CGFloat width = lblWidth;
UIFont *font = [UIFont fontWithName:fontName size:fontSize];
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:text
attributes:#
{
NSFontAttributeName: font
}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
return rect.size;
}
and finally use this code for dynamic create UILabel
CGFloat lbl_height = getLabelHeightForFont(#"System- System", address, 15, lbl_address.frame.size.width);
lbl_address.numberOfLines = 0;
lbl_address.textAlignment = NSTextAlignmentLeft;
[lbl_address setLineBreakMode:NSLineBreakByWordWrapping];
lbl_address.frame = CGRectMake(lbl_address.frame.origin.x, lbl_address.frame.origin.y, lbl_address.frame.size.width, lbl_height+5);
This is the very simplest function for getting dynamic height for labels. You can just use this function.
Here ceil is the predefind function for returns the smallest integer value.
And MAXHEIGHT is maximum height for uilabel for example you can give 1000 also for future caluclations...
-(CGFloat) getHeightForLabels : (UILabel *) label
{
CGSize widthMaxHeight = CGSizeMake(label.frame.size.width, MAXHEIGHT);
CGSize size;
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGSize boundingRect = [label.text boundingRectWithSize:widthMaxHeight
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:label.font}
context:context].size;
size = CGSizeMake(ceil(boundingRect.width), ceil(boundingRect.height));
return size.height;
}

sizeWithFont:constrainedToSize - iOS7

I have the following method that I used in iOS6 but with iOS7 I'm getting errors on
CGSize labelHeight = [tweetText sizeWithFont:[UIFont systemFontOfSize:13.0f] constrainedToSize:CGSizeMake(self.tweetsTableView.bounds.size.width - 84, 4000)];
full method below, any ideas on how to amend for iOS7?
- (CGFloat)heightForCellAtIndex:(NSUInteger)index {
NSDictionary *tweet = self.tweets[index];
CGFloat cellHeight = 50;
NSString *tweetText = tweet[#"text"];
CGSize labelHeight = [tweetText sizeWithFont:[UIFont systemFontOfSize:13.0f] constrainedToSize:CGSizeMake(self.tweetsTableView.bounds.size.width - 84, 4000)];
cellHeight += labelHeight.height;
return cellHeight;
}
I know this is an old question & late answer, but it's still very relevant,
This sizeWithFont method is now deprecated, this new method works best
NSString *content = **Whatever your label's content is expected to be**
CGSize maximumLabelSize = CGSizeMake(390, 1000);
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:13] forKey: NSFontAttributeName];
CGSize newExpectedLabelSize = [content boundingRectWithSize:maximumLabelSize options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil].size;
So you can adjust your label (or table cell etc) to
label.frame.size.height = newExpectedLabelSize.height;
I hope this helps, cheers, Jim.
Add this lines:
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300) options:NSStringDrawingUsesFontLeading attributes:#{NSFontAttributeName: font} context:nil];
CGSize stringSize= new.size;

Fit text in UILabel

Here is my code
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 50, 300, 50)];
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.textColor.font = [UIFont fontWithName:#"Verdana" size:30];
label.text = #"A very long string";
etc...
The problems is that the font is large and can't fit in the label. It just display "A very"
What to do so entire text to be displayed.
I have tried
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
But it doesn't work for me.
I want to do that programmatically.
//EDIT
CGRect frame = CGRectMake(10, 50, 300, 50);
NSString *labelString = #"Players.";
UILabel *howManyUsersLabel = [[UILabel alloc]initWithFrame:frame];
howManyUsersLabel.textAlignment = UITextAlignmentCenter;
howManyUsersLabel.backgroundColor = [UIColor clearColor];
howManyUsersLabel.textColor = [UIColor whiteColor];
howManyUsersLabel.adjustsFontSizeToFitWidth = NO;
howManyUsersLabel.numberOfLines = 0;
CGFloat fontSize = 30;
while (fontSize > 0.0)
{
CGSize size = [labelString sizeWithFont:[UIFont fontWithName:#"Verdana" size:fontSize] constrainedToSize:CGSizeMake(frame.size.width, 10000) lineBreakMode:UILineBreakModeWordWrap];
if (size.height <= frame.size.height) break;
fontSize -= 1.0;
NSLog(#"test");
}
howManyUsersLabel.font = [UIFont fontWithName:#"Verdana" size:fontSize];
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).
Finally I got solution for text allignment issue in arabic language you just do like this:
label.text = #"هذا هو نص طويل جدا";
label.textAlignment = NSTextAlignmentNatural;
CGSize size = [labels sizeThatFits:CGSizeMake(_lblAddress.width, CGFLOAT_MAX)];
label.height = size.height;
[UILabel sizeToFit];
It will work for your problem.
Swift with iOS 9
let maxFontSize: CGFloat = 40
let minFontSize: CGFloat = 10
label.font = UIFont(name: label.font.fontName, size: maxFontSize)!
label.adjustsFontSizeToFitWidth = true
label.minimumScaleFactor = minFontSize/maxFontSize
This doesn't increase the font size to fill the label. It just starts with the max size and decreases as necessary down to the minimum. This is also assuming that the number of lines is 1.
CGRect titleRect = CGRectMake(10, 50, 300, 50);
UILabel *textTitleView = [[UILabel alloc] initWithFrame:titleRect];
textTitleView.numberOfLines = 3 //for multiple lines;
textTitleView.lineBreakMode = UILineBreakModeWordWrap;
[UIFont fontWithName:#"Verdana" size:30];
textTitleView.text = #"your text";
Interface Builder lets you do this now.
In UILabel, under Autoshrink, select "Minimum Font Size" instead of "Fixed Font Size".
Set the Minimum Font Size to be something reasonable, like 8.
You can also check the checkmark "Tighten Letter Spacing".
Alternatively you can do it programmatically:
label.adjustsFontSizeToFitWidth = YES;
Everything seems to be broken in iOS 8 (probably iOS 7 too).
Solution:
-(UIFont*)fontForString:(NSString*)string toFitInRect:(CGRect)rect seedFont:(UIFont*)seedFont {
UIFont* returnFont = seedFont;
CGSize stringSize = [string sizeWithAttributes:#{NSFontAttributeName : seedFont}];
while(stringSize.width > rect.size.width){
returnFont = [UIFont systemFontOfSize:returnFont.pointSize -1];
stringSize = [string sizeWithAttributes:#{NSFontAttributeName : returnFont}];
}
return returnFont;
}
Make sure you don't try and use label.adjustsFontSizeToFitWidth = YES otherwise it'll get really confused and the new size won't work properly.