Increase height of cell without configuring it? - ios

I have so UITableView in that i have custom cell.That custom cell contains some labels .The text of label can be dynamic depending upon the Json. Now i want to make the height of cell based on the content height of the label so i have used the method heightForRowAtINdexPath.Now i am getting the cell like this.
if(!self.customCell)
{
self.customCell = [self.table_view dequeueReusableCellWithIdentifier:#"homeCell"];
}
the labels can be multiline depending upon the data.So i if write the same code of cellForRowAtiNdexPath in heightForRowAtIndexPath then i get more height.but if i don't write the same code then i get less height for labels.
as of now i have written below code for heightForRowAtIndexPath.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat height;
float like_height,c_one_height,c_two_height,c_three_height,tv_height,header_height,operations_height,img_like_icon_height,img_comment_icon_height,header_margin=5,tv_container_margin=5,operations_margin=5,like_top_margin=11,first_comment=10,second_comment=5,third_comment=5;
//define variables here
if(!self.customCell)
{
self.customCell = [self.table_view dequeueReusableCellWithIdentifier:#"homeCell"];
}
Post *user_post=[arr_post objectAtIndex:indexPath.row];
int like_count=[user_post.like_count intValue];
float comment_count=[user_post.comment_count intValue];
if (self.customCell.beizer_image != nil)
{
NSLog(#"inside cell beizer");
[self.customCell.beizer_image removeFromSuperview];
self.customCell.beizer_image=nil;
self.customCell.tv_post.textContainer.exclusionPaths=NULL;
self.customCell.beizer_path=nil;
}
[self.customCell setSelectionStyle:UITableViewCellSelectionStyleNone];
self.customCell.tv_post.text=user_post.post_description;
self.customCell.tv_post.font = [UIFont fontWithName:user_post.font_family size:[user_post.font_size floatValue]];
[self.customCell.tv_post setTextColor:[self colorFromHexString:user_post.font_color]];
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
NSLog(#"NOT INSIDE THE CONDITION");
}
else
{
NSLog(#"INSIDE BEIZER PATH CONDITION");
self.customCell.beizer_path = [UIBezierPath bezierPathWithRect:CGRectMake(5, 5, 100, 100)];
self.customCell.tv_post.textContainer.exclusionPaths = #[self.customCell.beizer_path];
self.customCell.beizer_image =[[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 100, 100)];
if(![user_post.post_image isEqualToString:#"none"])
{
[self.customCell.beizer_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_image]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
if(![user_post.post_video isEqualToString:#"none"])
{
[self.customCell.beizer_image setImageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_post.post_video_thumbnail]]placeholderImage:[UIImage imageNamed:#"post_placeholder.png"]];
}
[self.customCell.tv_post addSubview:self.customCell.beizer_image];
}
//make textview height dynamic
self.customCell.tv_post.scrollEnabled=NO;
if([user_post.post_image isEqualToString:#"none"] && [user_post.post_video isEqualToString:#"none"])
{
CGFloat fixedWidth = self.customCell.tv_post.frame.size.width;
CGSize newSize = [self.customCell.tv_post sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = self.customCell.tv_post.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
self.customCell.tv_post.frame = newFrame;
self.customCell.tv_height.constant=self.customCell.tv_post.frame.size.height;
[self.customCell.view_tvContainer layoutIfNeeded];
}
else
{
CGFloat fixedWidth = self.customCell.tv_post.frame.size.width;
CGSize newSize = [self.customCell.tv_post sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = self.customCell.tv_post.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth),fmax(self.customCell.beizer_image.frame.size.height+10,newSize.height));
self.customCell.tv_post.frame = newFrame;
self.customCell.tv_height.constant=self.customCell.tv_post.frame.size.height;
[self.customCell.view_tvContainer layoutIfNeeded];
}
// self.customCell.f_comment_top.constant=-2100;
// [self.customCell layoutIfNeeded];
if(like_count>0)
{
like_height=self.customCell.label_like_count.frame.size.height;
}
else
{
like_height=0;
img_like_icon_height=0;
}
if(comment_count<=0)
{
c_one_height=0;
c_two_height=0;
c_three_height=0;
img_comment_icon_height=0;
}
else if(comment_count==1)
{
if(like_count<=0)
{
self.view.translatesAutoresizingMaskIntoConstraints = NO;
self.customCell.f_comment_top.constant=-21;
[self.customCell layoutIfNeeded];
}
c_one_height=self.customCell.first_comment.frame.size.height;
c_two_height=0;
c_three_height=0;
}
else if(comment_count==2)
{
if(like_count<=0)
{
self.view.translatesAutoresizingMaskIntoConstraints = NO;
self.customCell.f_comment_top.constant=-21;
[self.customCell layoutIfNeeded];
}
c_one_height=self.customCell.first_comment.frame.size.height;
c_two_height=self.customCell.second_cmment.frame.size.height+15;
c_three_height=0;
}
else if(comment_count==3)
{
if(like_count<=0)
{
// self.customCell.f_comment_top.constant=1020;
// [self.customCell.first_comment layoutIfNeeded];
}
else
{
}
c_one_height=self.customCell.first_comment.frame.size.height;
c_two_height=self.customCell.second_cmment.frame.size.height;
c_three_height=self.customCell.third_comment.frame.size.height+15;
}
tv_height=self.customCell.view_tvContainer.frame.size.height;
header_height=self.customCell.header_view_height.frame.size.height;
operations_height=self.customCell.view_operations_height.frame.size.height;
height = like_height+c_one_height+c_two_height+c_three_height+tv_height+operations_height+header_height;
CGFloat margin_height=header_margin+operations_margin+tv_container_margin+like_top_margin+first_comment+second_comment+third_comment+img_comment_icon_height+img_like_icon_height;
NSLog(#"like label height is %f",like_height);
NSLog(#"first comment height is %f",c_one_height);
NSLog(#"second comment height is %f",c_two_height);
NSLog(#"third comment height is %f",c_three_height);
NSLog(#"all margin height is %f",margin_height);
NSLog(#"height is %f",height);
// Padding of 1 point (cell separator)
height=height+margin_height;
CGFloat separatorHeight = 1;
return height;
}
I have seen many example in which it is written that for configuring cell the code of cellForRowAtIndexPath is written in heightForRowAtIndexPath.
Why i need to repeat the code for cellForRowAtIndexPath in
heightForRowAtIndexPath?

Why i need to repeat the code for cellForRowAtIndexPath in heightForRowAtIndexPath?
because heightForRowAtIndexPath will always get called before cellForRowAtIndexPath. So to calculate height in heightForRowAtIndexPath you have create that cell in heightForRowAtIndexPath.
Best way to use autolayout for dynamic height calculation:-
You can refer following Link to do the same.

There is no need to configure the entire cell which you have declared in cellForRowAtIndexPath in heightForRowAtIndexPath.
These are two methods used for specific functionality.
cellForRowAtIndexPath is a DataSource method which is meant for configuring your cell in tableview.
heightForRowAtIndexPath is a Delegate method which is meant to calculate the height of the tableviewcell or row based on the content which you are planning to show in cellForRowAtIndexPath.
For example, if you are configuring a cell with a UILabel (no matter how many labels) and assign the label with some text in cellForRowAtIndexPath, then in heightForRowAtIndexPath, fetch the text that you have assigned to label, calcluate label's height and give this height of the label to the cell. This will create the cell which have height according to your label's height.
For example, in your cellForRowAtIndexPath,
.....//your cell configuration code above//.....
UILabel *lbl_myText = [[UILabel alloc]initWithFrame:CGRectZero];
[lbl_myText setLineBreakMode:NSLineBreakByWordWrapping];
lbl_myText.minimumScaleFactor = FONT_SIZE;
[lbl_myText setNumberOfLines:0];
lbl_myText.textAlignment = NSTextAlignmentRight;
[lbl_myText setFont:[UIFont systemFontOfSize:FONT_SIZE]];
NSString *text = [arr_text objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(Your_MAX_LabelWidth, Your_MAX_LabelHeight);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
CGRect textRect = [text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
context:nil];
size = textRect.size;
[lbl_myText setText:text];
float widthIs = [lbl_myText.text
boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{ NSFontAttributeName:lbl_myText.font }
context:nil]
.size.width;
[lbl_myText setFrame:CGRectMake(X_co,Y_co,widthIs,size.height)];
in heightForRowAtIndexPath:
.....//NO cell configuration code above//.....
NSString *cellText = [arr_text objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(Your_MAX_LabelWidth, Your_MAX_LabelHeight);
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
////for message label
CGRect textRect = [cellText boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:[UIFont systemFontOfSize:FONT_SIZE], NSParagraphStyleAttributeName: paragraphStyle.copy}
context:nil];
CGSize labelsize = textRect.size;
///calculate Cell the height
CGFloat height = MAX(labelsize.height, your_defaultcell_height);
if(height == your_defaultcell_height)
{
return your_defaultcell_height + 10; //10 is buffer height
}
else
{
return height + 10; //10 is buffer height
}

Related

Why is the height of UITableViewCell is smaller than the height of its text?

I have a UITableView with UITableViewCells, I set the height of each cell in the function heightForRowAtIndexPath in the fallowing way:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
NSStringDrawingOptions opts = (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading);
CGSize boundingRect = CGSizeMake(450.f, CGFLOAT_MAX);
CGSize size = [cell.detailTextLabel.text boundingRectWithSize:boundingRect
options:opts
attributes:[cell.detailTextLabel.attributedText attributesAtIndex:0 effectiveRange:nil]
context:nil].size;
CGFloat height = size.height;
size = [cell.textLabel.text boundingRectWithSize:boundingRect
options:opts
attributes:[cell.textLabel.attributedText attributesAtIndex:0 effectiveRange:nil]
context:nil].size;
height += size.height;
return height;
}
But the cell that I get is too small for the text, and longer text doesn't fit:
The text that is written in cell is set in the following way:
NSString *nickName = #"some nickname"; // gets the nickname
NSString title = [NSString stringWithFormat:#"%# wrote:", nickName];
NSString *detail = #"some text"; // gets the content of the message
[cell.textLabel setText: title];
[cell.detailTextLabel setText: detail];
cell.detailTextLabel.numberOfLines = 0;
cell.detailTextLabel.lineBreakMode = NSLineBreakByWordWrapping;
Why is the height of the cell too short?
From method boundingRectWithSize:options:attributes:context:
https://developer.apple.com/reference/foundation/nsstring/1524729-boundingrectwithsize :
"This method returns the actual bounds of the glyphs in the string"
What is missing is the margins of the cell, which can be accessed with cell.layoutMargins:
height += cell.layoutMargins.top + cell.layoutMargins.bottom;
Try with the boundingRect method of NSAttributedString (Swift 3)
//change this value with the width of your UITableViewCell
let availableWidth:CGFloat = 355
let stringBoundingRect = NSAttributedString(string: "your string").boundingRect(with: CGSize(width: availableWidth, height: CGFloat.greatestFiniteMagnitude), options: [.usesDeviceMetrics, .usesLineFragmentOrigin], context: nil)
let height = stringBoundingRect.height
In Objective-C:
// change this value with the width of your UITableViewCell
CGFloat availableWidth = 355;
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:#"your string"];
CGRect stringBoundingRect = [attrStr boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX) options: NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesDeviceMetrics context:nil];
CGFloat height = stringBoundingRect.size.height;

Customized UITableViewCell Update Subviews

I have a customized a UITableviewCell. There is a title label and a detail label inside.
Now I want to adjust the detail label attributes according to the content.
If the string size is greater than the frame then set the number of line to 2.
I have tried to put the code in the cellForRowAtIndexPath or layoutSubViews in the cell class.
The piece of code is like
TransportationViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
UIFont* font = cell.detailLabel.font;
NSDictionary* attribute = #{NSFontAttributeName:font};
const CGSize textSize = [cell.detailLabel.text sizeWithAttributes: attribute];
if (textSize.width > cell.detailTextLabel.frame.size.width && cell.detailLabel.numberOfLines == 1) {
NSLog(#"%lf, %lf, %lu", cell.detailLabel.frame.size.width, textSize.width, (long)cell.detailLabel.numberOfLines);
cell.detailTextLabel.font = [UIFont systemFontOfSize:8];
cell.detailTextLabel.numberOfLines = 2;
[cell setNeedsLayout];
}
It actually passed the if condition but the setting of label doesn't work.
write below code in view didload
self.theTableView.estimatedRowHeight = 100;
self.theTableView.rowHeight = UITableViewAutomaticDimension;
[self.theTableView setNeedsLayout];
[self.theTableView layoutIfNeeded];
In cellForRowAtIndexpath cell.detailTextLabel.numberOfLines = 0;
set numberOfLines = 0;
this will solve your problem.
Edit 1: code for calculating dynamic height.
CGSize boundingBox = [label.text boundingRectWithSize:constraint
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName:label.font}
context:context].size;
Thne on the basis of this height you can do the further calculations.
For more info, you can check this answer https://stackoverflow.com/a/27374760/5660422

Setting UILabel height in cellForRowAtIndexPath is not actually changing my label height when I run the app

I am trying to set the height of my label inside of my UITableViewCell dynamically at runtime. The height of the label is dependent on the content. I have set in my custom UITableViewCell xib file that the UILabel should have 0 lines (no bounds). Below is my code for CellForRowAtIndexPath. I've looked around and tried a few things but nothing seems to work for me.
XYZPlayerTableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int row = indexPath.row;
static NSString *CellIdentifier = #"PlayerCell";
XYZPlayerTableViewCell *cell = (XYZPlayerTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
XYZPlayer *player = [self.players objectAtIndex:row];
NSString *nameText = player.name;
NSString *gameText = player.game;
cell.nameLabel.text = nameText;
cell.gameLabel.text = gameText;
[cell.gameLabel sizeToFit];
cell.gameLabel.numberOfLines = 0;
cell.ratingImageView.image = [self imageForRating:player.rating];
CGSize boundingRect = CGSizeMake(cell.frame.size.width, 4000);
CGRect expectedFrame = [cell.gameLabel.text boundingRectWithSize:boundingRect options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: cell.gameLabel.font} context:nil];
cell.gameLabel.frame = expectedFrame;
NSLog(#"gameLabel = 0x%# gameText = %# gameLabelHeight = %.2f", cell.gameLabel, gameText, expectedFrame.size.height);
return cell;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
int row = indexPath.row;
//set width depending on device orientation
self.cellPrototype.frame = CGRectMake(self.cellPrototype.frame.origin.x, self.cellPrototype.frame.origin.y, tableView.frame.size.width, self.cellPrototype.frame.size.height);
// Get variables
XYZPlayer *player = [self.players objectAtIndex:row];
UILabel *nameLabel = self.cellPrototype.nameLabel;
NSString *nameText = player.name;
UILabel *gameLabel = self.cellPrototype.gameLabel;
NSString *gameText = player.game;
// Calculate height
CGFloat nameLabelHeight = [self sizeOfLabel:nameLabel withText:nameText].height;
CGFloat gameLabelHeight = [self sizeOfLabel:gameLabel withText:gameText].height;
CGFloat padding = nameLabel.frame.origin.y;
CGFloat combinedHeight = padding + nameLabelHeight + padding/2 + gameLabelHeight + padding;
return combinedHeight;
}
XYZPlayerTableViewCell.m
-(void)setGameLabelHeightForString:(NSString *)string
{
self.gameLabel.numberOfLines = 0;
gameLabel.text = string;
CGSize maximumLabelSize = CGSizeMake(gameLabel.frame.size.width, FLT_MAX);
CGSize expectedLabelSize = [string sizeWithFont:self.gameLabel.font constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];
CGRect newFrame = self.gameLabel.frame;
newFrame.size.height = expectedLabelSize.height;
self.gameLabel.frame = newFrame;
}
-(void) layoutSubviews
{
[self setGameLabelHeightForString:gameLabel.text];
}
The output at runtime is this:
2014-07-09 00:21:32.277 MyTestApp[24503:60b]
gameLabel = 0x< UILabel: 0x8e42800; frame = (0 0; 321.946 81.124); text = 'Tic-Tac-Toe And another l...'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = < CALayer: 0x8e360d0>>
gameText = Tic-Tac-Toe And another line and maybe some more because who know's how long this can go. I think i need just a little bit more text to make this super obvious
gameLabelHeight = 81.12
And this is what my app looks like. The gray color shows the height of my label
Any one got any ideas of what I'm doing wrong?
You could use this to calculate height but it is not a recommended way
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
XYZPlayerTableViewCell *cell=(XYZPlayerTableViewCell *)[self tableView:tblView cellForRowAtIndexPath:indexPath];
return CGRectGetMaxX(cell.gameLabel.frame)+5;
}
use one more line of code
cell.gameLabel.numberOfLines = 0;
To resize your Label according to your content you have to make sure of 2 things
Number of lines = 0
and call sizeToFit on your label.
Not sure if you are setting the lines. Try to set the lines inside delegate only, else it seems ok
UILabel *tempLabel = [[UILabel alloc]initWithFrmae:_textView.bounds];
tempLabel.numberOfLines = 0; // Important to do
tempLabel.text = #"Your Text";
[tempLabel sizeToFit]; // This will resize your Label and now you can use it's height to manage your textView.
This will resize the tempLabel according to it's text.
Try to set the numberOfLines inside the delegate only.
Also try to give the height of your cell according to your Labels by calculating them inside heightForRowAtIndexPath delegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
float calulatedWidth = [self getWidthFromString:textTobePutInLabel];
float calculatedHeight = [self getHeightFromString:textTobePutInLabel];
cell.gameLabel.frame = CGRectMake(yourX,yourY,calulatedWidth,calculatedHeight)
cell.gameLabel.text = gameText;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
float height = [self getHeightFromString:textTobePutInLabel];
return height;
}
- (float)getWidthFromString:(NSString *)strName{
CGSize maximumSize = CGSizeMake(9999, 9999);
CGSize size = [strName boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: [UIFont fontWithName:MAVEN_PRO size:13.0f]} context:nil].size;
return size.width;
}
- (float)getHeightFromString:(NSString *)strName{
CGSize maximumSize = CGSizeMake(9999, 9999);
CGSize size = [strName boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: [UIFont fontWithName:MAVEN_PRO size:13.0f]} context:nil].size;
return size.height;
}
You need to do two things
Override heightForRowAtIndexPath of UITableViewDelegate to return height of the cell dynamically based on the text.
Override layoutSubviews of UITableViewCell (XYZPlayerTableViewCell) to recalculate and set the frame for label.
YOu can use
CGSize labelSize = [self.gameLabel.text sizeWithFont:[UIFont systemFontOfSize:11]
constrainedToSize:CGSizeMake(300, NOTIFICATION_DESC_MAX_HEIGHT + 5)
lineBreakMode:NSLineBreakByWordWrapping];
for calculating best fitted height if you are setting String to label or
CGRect rect = [self.gameLabel.attributedText boundingRectWithSize:CGSizeMake(300, NOTIFICATION_DESC_MAX_HEIGHT + 5)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
context:nil];
if you are using AttributedString for your label
-- Vishal
I've checked your code and I noticed one problem with the statement [gameLabel sizeToFit]; to be placed after setting the frame for the label.
i.e., after these lines
CGSize boundingRect = CGSizeMake(cell.frame.size.width, 4000);
CGRect expectedFrame = [cell.gameLabel.text boundingRectWithSize:boundingRect options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: cell.gameLabel.font} context:nil];
cell.gameLabel.frame = expectedFrame;

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.

UILabel sizeThatFits not working

I'm trying to calculate the height for a UITableViewCell so I've defined a class method that looks like this
+ (CGFloat)heightWithText:(NSString *)text
{
SizingLabel.text = text;
[SizingLabel sizeThatFits:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)];
return (TOP_MARGIN + SizingLabel.frame.size.height + BOTTOM_MARGIN);
}
I've defined SizingLabel like this:
+ (void)initialize
{
SizingLabel = [[UILabel alloc] initWithFrame:CGRectZero];
SizingLabel.numberOfLines = 0;
SizingLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
However, if i stick a breakpoint in the -heightWithText: method, i notice that the dimensions of SizingLabel never change and i thus get an incorrect value. Why is that?
As said above, sizeThatFits: (and thus sizeToFit) do not work well with UILabel objects.
You better use the preferred textRectForBounds:limitedToNumberOfLines: method:
+ (CGFloat)heightWithText:(NSString *)text
{
resizingLabel.text = text;
CGSize labelSize = [resizingLabel textRectForBounds:CGRectMake(0.0, 0.0, LABEL_WIDTH, CGFLOAT_MAX)
limitedToNumberOfLines:0].size; // No limit
return (TOP_MARGIN + labelSize.height + BOTTOM_MARGIN);
}
+ (CGFloat)heightWithText:(NSString *)text
{
SizingLabel.text = text;
CGSize labelSize = [SizingLabel sizeThatFits:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)];
return (TOP_MARGIN + labelSize.height + BOTTOM_MARGIN);
}
Do this in your Custom Cell Class:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
//Message Label
lbl_name = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 300, 25)];
[lbl_name setFont:[UIFont fontWithName:#"Helvetica" size:16.0f]];
lbl_name.lineBreakMode = UILineBreakModeWordWrap;
lbl_name.numberOfLines = 0;
[lbl_name sizeToFit];
[self.contentView addSubview:lbl_name];
//Time
}
return self;
}
-(void)resizeNameLabel:(NSString *)text
{
CGSize constraint = CGSizeMake(300 , 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:16.0f] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
[lbl_name setFrame:CGRectMake(10, 5, 300, MAX(size.height, 25.0f))];//300 Label Width
[lbl_name setText:text];
}
Do this in main class..
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil)
{
cell = (CustomCell *)[[CustomCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"cell"];
}
[((CustomCell *)cell) resizeNameLabel:text];
return cell;
}
Just do like this...
below code is to calculate the rect for dynamic text length (ios7 version)
- (CGRect)labelFrameWithText:(NSString *)text
{
CGRect rect;
// the font of your text
UIFont *font = [UIFont systemFontOfSize:15.0];
NSDictionary *attributes = #{NSFontAttributeName: font};
// the first parametric CGSize is the max size that the rect's size can be
CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(youImageWidth, 100.0)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
//the rect of the UILabel
//This method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.
rect = CGRectMake(yourLabelOriginX,
yourLabelOriginY,
ceil(boundingRect.size.width),
ceil(boundingRect.size.height));
return rect;
}
and after you get the rect, use it to calculate your cell size
----------------older version-------------------
CGSize contentSize = [content sizeWithFont:font
constrainedToSize:CGSizeMake(maxWidth, maxHeight)
lineBreakMode: NSLineBreakByWordWrapping];
For simple sizing of UILabels that have attributed text, I added this category to UILabel.
#implementation UILabel (PAUtils)
- (CGSize)jb_attributedSizeThatFits:(CGSize)size
{
CGRect textRect = [self.attributedText boundingRectWithSize:size options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];
return textRect.size;
}
#end
Two things to note:
When not setting attributedText (but instead just using text) this method doesn't take into account the numberOfLines property.
boundingRectWithSize returns fractions of points. If you are using the values returned from this method for layouts, you should probably ceilf the width and height.

Resources