Fit Text in UItableView Cell - ios

I have a long label that is my first label, and I want to fit it in my cell. This is what I have but it isn't working.
I have a custom UITabelviewCell with a few labels in it.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.row) {
case 0:{
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [diningHallTimes[indexPath.row][#"description"] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2) + 40;
// return myStringSize.height;
break;
}
default:
return 40;
break;
}
}
Here is cell for row
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DiningInfoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [diningHallTimes[indexPath.row][#"description"] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
CGFloat height = MAX(size.height, 44.0f);
CGFloat the = height + (CELL_CONTENT_MARGIN * 2);
cell.descriptionLabel.numberOfLines = 0;
[cell.descriptionLabel setFrame:CGRectMake(20, 0, 280, the)];
NSLog(#"%f", the);
cell.descriptionLabel.text = diningHallTimes[indexPath.row][#"description"];
cell.daysLabel.text = diningHallTimes[indexPath.row][#"days"];
cell.timeLabel.text = diningHallTimes[indexPath.row][#"time"];
return cell;
}
But then this is what my cell looks like
Not sure why this is happening, I am running iOS8, but I need it to work for both is and 7.
Thanks for the help in advance.

You need to calculate boundingRectWithSize: for label text. Also need to calculate number of lines required for updated content also. Try this below method to calculate new frame for label.
- (UILabel *) updateLabelFrame:(UILabel *)label {
CGRect lblRect = label.frame;
CGSize maxSize = CGSizeMake(label.frame.size.width, MAXFLOAT);
CGRect labelRect = [label.text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:label.font} context:nil];
CGFloat labelHeight = labelRect.size.height;
// For below line 16 is default height (The height before content is set). Change this value
// as per your requirement
int lines = labelHeight / 16; // Here 16 is a fix height (default height) for label.
[label setNumberOfLines:lines];
lblRect.size.height = labelHeight;
[label setFrame:lblRect];
return label;
}
Edit:
You can place this method any where you want. Like some base class or in same view controller. Here I modified above method which will return label with dynamic frame.
For your case you need to place this method in view controller class. Then call this method in -cellForRowAtIndexPath after content is updated for label. See below code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
DiningInfoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [diningHallTimes[indexPath.row][#"description"] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
CGFloat height = MAX(size.height, 44.0f);
CGFloat the = height + (CELL_CONTENT_MARGIN * 2);
cell.descriptionLabel.numberOfLines = 0;
[cell.descriptionLabel setFrame:CGRectMake(20, 0, 280, the)];
NSLog(#"%f", the);
cell.descriptionLabel.text = diningHallTimes[indexPath.row][#"description"];
cell.daysLabel.text = diningHallTimes[indexPath.row][#"days"];
cell.timeLabel.text = diningHallTimes[indexPath.row][#"time"];
// Update descriptionLabel height.
cell.descriptionLabel = [self updateLabelFrame:cell.descriptionLabel];
return cell;
}

You have to set up Autolayout constraints for the label and create a prototype cell with the content. And then you have to return then you have to get the height of the cell.
For reference , you could see the following video
https://www.youtube.com/watch?v=6KImie4ZMwk

Try [yourLabel sizeToFit] or you may use [yourLabel sizeThatFit:CGFrame];

Related

How to set cell height based on UILabel inside custom cell

I have used UITableView to display items from database and I have created custom UITableViewCell which has a few labels. My largest label is name Description.
Each cell can have different height but I can't figure out how to set dynamic cell height.
All I get is three dots at the end of the label and height for cell is always about 50.
How to make cell height based on label inside it?
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 10.0f
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = _orderProperty.Description;
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]
constrainedToSize:constraint
lineBreakMode:NSLineBreakByWordWrapping];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
UPDATE
static NSString *CellIdentifier = #"orderDetailCell";
OrderDetailCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
[tableView registerNib:[UINib nibWithNibName:#"OrderDetailCustomCell" bundle:nil] forCellReuseIdentifier:CellIdentifier];
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
OrderProperty* item = [_list objectAtIndex:indexPath.row];
cell.Title.text = item.Title;
NSString* _description = item.Description;
cell.Description.text = _description;
You can try something like this
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
int rowHeight =0.0f;
NSString *stringToSize=[NSString stringWithFormat:#"%#",longStringValue];
CGSize size = [stringToSize
sizeWithFont:[UIFont systemFontOfSize:15.0f]
constrainedToSize:CGSizeMake(300, 6000)
lineBreakMode:NSLineBreakByWordWrapping];
rowHeight = size.height+10;
return rowHeight;
}
you may get the longStringValue from the array that you are using as a dataSource for your table
You can use following category on NSString, which use NSTextContainer and NSTextContainer to calculate the exact size of your text.
NSString+Calculation.m
And your final code will be like this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = _orderProperty.Description;
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text usedSizeForMaxWidth:constraint.width
withFont:[UIFont systemFontOfSize:FONT_SIZE]];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
sizeWithFont is now deprecated, please use the method below to set the height of the sell according the the text within the label.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
OrderProperty* item = [_list objectAtIndex:indexPath.row];
NSString *text = item.Description;
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[UIFont fontWithName:#"Helvetica" size:13] forKey:NSFontAttributeName];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize expectedLabelSize = [content boundingRectWithSize: constraint options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil].size;
return expectedLabelSize.height+CELL_CONTENT_MARGIN * 2);
}
Obviously you will need to adjust the string attributes to whatever you are using. These are simply for calculating the required height of the cell.

Dynamic height of the cell is wrong sometimes

I have a UILabel in a cell and I need to change the height of the UILabel dynamically. So the cell is a xib file with height 44 and label 240x44 and label autosizing horizontally and vertically. The font is 15.0f size, system. Number of lines = 0, wrap by word.
So I have the method
+ (CGFloat) cellHeightForString: (NSString *) string
{
CGFloat cellHeight = [string sizeWithFont:[UIFont systemFontOfSize:15.0f] constrainedToSize:CGSizeMake(240.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping].height;
return cellHeight < 44.0f ? 44.0f : cellHeight;
}
but the height of the cell is sometimes smaller so not all lines of the text are shown in the cell. Can't understand what I'm doing wrong.. Any help?
Try this,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// add your code snippet here
// dynamically change the label height,
CGSize textSize = {
200.0, // limit width
20000.0 // and height of text area
};
CGSize contentSize = [yourText sizeWithFont:[UIFont systemFontOfSize:15.0] constrainedToSize:textSize lineBreakMode:NSLineBreakByWordWrapping];
CGFloat contentHeight = contentSize.height < 36? 36: contentSize.height; // lower bound for height
CGRect labelFrame = [yourLabel frame];
yourLabel.size.height = contentHeight;
[yourLabel setFrame: labelFrame];
[yourLabel setText:yourText];
return cell;
}
Dynamically change the cell height,
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
YourCell *currentCell = (YourCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
// change hard coded value based on your cell alignment
int cellLength=[currentCell.yourLabel.text length]/42;
cellLength = cellLength*22 > 200 ? cellLength*22 : 200;
CGSize constraint = CGSizeMake((200 - 10), cellLength);
CGSize size1 = [cellText sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
return 220+size1.height;
}

Dynamic label width in UITableView [duplicate]

This question already has answers here:
Change the label width dynamically inside a UITableViewCell
(3 answers)
Closed 9 years ago.
I am trying to set the label width dynamically based on the content of the other label on the same line.
I am implementing the logic inside the "cellForRowAtIndexPath"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"rowNumber:%d", indexPath.row);
EntityTableViewCell *cell = nil;
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.companyNameLabel.text = [group1 objectAtIndex:indexPath.row];
cell.companyCROfficeAddrLabel.text = [group2 objectAtIndex:indexPath.row];
cell.companyBusinessAddrLabel.text = [group3 objectAtIndex:indexPath.row];
cell.timestamp.text = [Utils getDateTimeString:[group4 objectAtIndex:indexPath.row]];
[cell.companyLogoImageView setImageWithURL:[NSURL URLWithString:[myArray objectAtIndex:indexPath.row] ]
placeholderImage:[UIImage imageNamed: #"profile-image-placeholder"]
options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
//logics to dynamically change the label width to maximum utilize the realstate
CGFloat timeStampWidth = [cell.timestamp.text sizeWithFont:cell.timestamp.font].width;
CGFloat ksCompanyNameLableMaxWidth = 235;
NSLog(#"timeStampWidth:%f", timeStampWidth);
CGSize companyNameLableSize = CGSizeMake((ksCompanyNameLableMaxWidth - timeStampWidth), cell.companyNameLabel.frame.size.height);
CGRect newFrame = cell.companyNameLabel.frame;
newFrame.size = companyNameLableSize;
cell.companyNameLabel.frame = newFrame;
NSLog(#"companyLableWidth:%f", newFrame.size.width);
return cell;
}
There are multiple problems with this code.
As the table is initialised, although this piece of code is called for every cell. The width of the label is still set as the size in the story board. On the other side, if I scroll down, the label is displayed correctly as designed in the code.
Because I also have a tabView controller within my app, whenever I switch between the tabs, the dynamically populated label width is getting updated with the default label width set in the storyboard again.
Could someone please tell me what I did wrong and suggest some solution?
Thanks
try this code
#define FONT_SIZE 14.0f
#define CELL_CONTENT_MARGIN 8.0f
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *text = [BugComments_text objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(tableView.frame.size.width - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
CGFloat height = MAX(size.height+40, 60.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [arrayofdata objectAtIndex:indexPath.row];
CGSize constraint = CGSizeMake(tableView.frame.size.width - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
[cell.Content_Text setText:text];
cell.Content_Text setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN+cell.Content_Email.frame.origin.y+cell.Content_Email.frame.size.height, tableView.frame.size.width - (CELL_CONTENT_MARGIN * 2), MAX(size.height,20.0f))];
}
Try this in your cellForRowAtIndexPath for dynamically setting the company label text,
CGSize textSize = {
200.0, // limit width
20000.0 // and height of text area
};
CGSize contentSize = [yourText sizeWithFont:[UIFont systemFontOfSize:17.0] constrainedToSize:textSize lineBreakMode:NSLineBreakByWordWrapping];
CGFloat contentHeight = contentSize.height < 36? 36: contentSize.height; // lower bound for height
CGRect companyLabelFrame = [cell.companyNameLabel frame];
companyLabelFrame.size.height = contentHeight;
[cell.companyNameLabel setFrame:companyLabelFrame];
cell.companyNameLabel setText:yourText];
I finally solve the problem by clearly specifying it again and get the answer from #rdelmar
please look the link Here

ios - can't get the UITableView cell height to be proportional to the amount of text

I am trying to get the UITableView cells to fit the text. So far I have something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel *label = nil;
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault)
reuseIdentifier:#"business"];
NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(#"comment")];
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);
CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setText:comment];
[label setFrame:CGRectMake(10, 10, 320 - (10 * 2), MAX(size.height, 44.0f))];
cell.textLabel.text = comment;
}
I also have this function
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(#"comment")];
CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);
CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (10 * 2);
}
But it isn't allocating the right amount of height to the cells of the UITableViews. I think I am making some mistakes with how/where I assign the label and the text of the cells.
Please help me understand how it should be.
Thanks!
does this get you closer?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"business"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault)reuseIdentifier:#"business"];
}
NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(#"comment")];
CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);
CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, MAX(size.height, 44.0f) + 20.0f)];
label.numberOfLines = 0;
label.lineBreakMode = UILineBreakModeWordWrap;
label.text = comment;
[cell.contentView addSubview:label];
}
You need to set height of a cell using -tableView:heightForRowAtIndexPath.
With the new code posted
Here is how I did it (I used a prototype cell so things may be different for you).
I set the the autosizing of the cell to auto size the height of the label (this may already be set for the textLabel).
Then in -tableView:heightForRowAtIndexPath I did the following:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
CGSize size = CGSizeMake(WIDTH_OF_PROTOTYPE_LABEL, CGFLOAT_MAX);
size = [TEXT_AT_INDEX_PATH sizeWithFont:FONT_OF_PROTOTYPE_LABEL constrainedToSize:size lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = size.height + (HEIGHT_OF_PROTOTYPE_CELL - HEIGHT_OF_PROTOTYPE_LABEL);
return MAX(height, HEIGHT_OF_PROTOTYPE_CELL);
}
Update 2
In looking at your code again, I see two possible problems. 1) You have the width of the textLabel wrong. 2) You should compute the do MAX as the last thing after you compute the final new height.

Setting custom UITableViewCells height

I am using a custom UITableViewCell which has some labels, buttons and image views to be displayed. There is one label in the cell whose text is a NSString object and the length of string could be variable. Due to this, I cannot set a constant height to the cell in the UITableView's heightForCellAtIndex method. The cell's height depends on the label's height which can be determined using the NSString's sizeWithFont method. I tried using it, but it looks like I'm going wrong somewhere. How can it be fixed?
Here is the code used for initializing the cell.
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])
{
self.selectionStyle = UITableViewCellSelectionStyleNone;
UIImage *image = [UIImage imageNamed:#"dot.png"];
imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(45.0,10.0,10,10);
headingTxt = [[UILabel alloc] initWithFrame: CGRectMake(60.0,0.0,150.0,post_hdg_ht)];
[headingTxt setContentMode: UIViewContentModeCenter];
headingTxt.text = postData.user_f_name;
headingTxt.font = [UIFont boldSystemFontOfSize:13];
headingTxt.textAlignment = UITextAlignmentLeft;
headingTxt.textColor = [UIColor blackColor];
dateTxt = [[UILabel alloc] initWithFrame:CGRectMake(55.0,23.0,150.0,post_date_ht)];
dateTxt.text = postData.created_dtm;
dateTxt.font = [UIFont italicSystemFontOfSize:11];
dateTxt.textAlignment = UITextAlignmentLeft;
dateTxt.textColor = [UIColor grayColor];
NSString * text1 = postData.post_body;
NSLog(#"text length = %d",[text1 length]);
CGRect bounds = [UIScreen mainScreen].bounds;
CGFloat tableViewWidth;
CGFloat width = 0;
tableViewWidth = bounds.size.width/2;
width = tableViewWidth - 40; //fudge factor
//CGSize textSize = {width, 20000.0f}; //width and height of text area
CGSize textSize = {245.0, 20000.0f}; //width and height of text area
CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:11.0f]
constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat ht = MAX(size1.height, 28);
textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
textView.text = postData.post_body;
textView.font = [UIFont systemFontOfSize:11];
textView.textAlignment = UITextAlignmentLeft;
textView.textColor = [UIColor blackColor];
textView.lineBreakMode = UILineBreakModeWordWrap;
textView.numberOfLines = 3;
textView.autoresizesSubviews = YES;
[self.contentView addSubview:imageView];
[self.contentView addSubview:textView];
[self.contentView addSubview:webView];
[self.contentView addSubview:dateTxt];
[self.contentView addSubview:headingTxt];
[self.contentView sizeToFit];
[imageView release];
[textView release];
[webView release];
[dateTxt release];
[headingTxt release];
}
This is the label whose height and width are going wrong:
textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
Your UITableViewDelegate should implement tableView:heightForRowAtIndexPath:
Objective-C
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [indexPath row] * 20;
}
Swift 5
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.row * 20
}
You will probably want to use NSString's sizeWithFont:constrainedToSize:lineBreakMode: method to calculate your row height rather than just performing some silly math on the indexPath :)
If all your rows are the same height, just set the rowHeight property of the UITableView rather than implementing the heightForRowAtIndexPath. Apple Docs:
There are performance implications to using tableView:heightForRowAtIndexPath: instead of rowHeight. Every time a table view is displayed, it calls tableView:heightForRowAtIndexPath: on the delegate for each of its rows, which can result in a significant performance problem with table views having a large number of rows (approximately 1000 or more).
in a custom UITableViewCell -controller add this
-(void)layoutSubviews {
CGRect newCellSubViewsFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
CGRect newCellViewFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
self.contentView.frame = self.contentView.bounds = self.backgroundView.frame = self.accessoryView.frame = newCellSubViewsFrame;
self.frame = newCellViewFrame;
[super layoutSubviews];
}
In the UITableView -controller add this
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [indexPath row] * 1.5; // your dynamic height...
}
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f
#define CELL_CONTENT_MARGIN 10.0f
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
/// Here you can set also height according to your section and row
if(indexPath.section==0 && indexPath.row==0)
{
text=#"pass here your dynamic data";
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
else
{
return 44;
}
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
UILabel *label = nil;
cell = [tv dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"Cell"];
}
********Here you can set also height according to your section and row*********
if(indexPath.section==0 && indexPath.row==0)
{
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
label.backgroundColor=[UIColor clearColor];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
// NSString *text1 =[NSString stringWithFormat:#"%#",text];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
if (!label)
label = (UILabel*)[cell viewWithTag:1];
label.text=[NSString stringWithFormat:#"%#",text];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
[cell.contentView addSubview:label];
}
return cell;
}
I saw a lot of solutions but all was wrong or uncomplet.
You can solve all problems with 5 lines in viewDidLoad and autolayout.
This for objetive C:
_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
For swift 2.0:
self.tableView.estimatedRowHeight = 80
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
Now create your cell with xib or into tableview in your Storyboard
With this you no need implement nothing more or override. (Don forget number os lines 0) and the bottom label (constrain) downgrade "Content Hugging Priority -- Vertical to 250"
You can donwload the code in the next url:
https://github.com/jposes22/exampleTableCellCustomHeight
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
CGSize constraintSize = {245.0, 20000}
CGSize neededSize = [ yourText sizeWithFont:[UIfont systemFontOfSize:14.0f] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeCharacterWrap]
if ( neededSize.height <= 18)
return 45
else return neededSize.height + 45
//18 is the size of your text with the requested font (systemFontOfSize 14). if you change fonts you have a different number to use
// 45 is what is required to have a nice cell as the neededSize.height is the "text"'s height only
//not the cell.
}
To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.
Assign and implement tableview dataSource and delegate
Assign UITableViewAutomaticDimension to rowHeight & estimatedRowHeight
Implement delegate/dataSource methods (i.e. heightForRowAt and return a value UITableViewAutomaticDimension to it)
-
Objective C:
// in ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property IBOutlet UITableView * table;
#end
// in ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.table.dataSource = self;
self.table.delegate = self;
self.table.rowHeight = UITableViewAutomaticDimension;
self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Swift:
#IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
For label instance in UITableviewCell
Set number of lines = 0 (& line break mode = truncate tail)
Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.
Note: If you've more than one labels (UIElements) with dynamic length, which should be adjusted according to its content size: Adjust 'Content Hugging and Compression Resistance Priority` for labels which you want to expand/compress with higher priority.
Here in this example I set low hugging and high compression resistance priority, that leads to set more priority/importance for contents of second (yellow) label.
Thanks to all the posts on this topic, there are some really helpful ways to adjust the rowHeight of a UITableViewCell.
Here is a compilation of some of the concepts from everyone else that really helps when building for the iPhone and iPad. You can also access different sections and adjust them according to the varying sizes of views.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
int cellHeight = 0;
if ([indexPath section] == 0)
{
cellHeight = 16;
settingsTable.rowHeight = cellHeight;
}
else if ([indexPath section] == 1)
{
cellHeight = 20;
settingsTable.rowHeight = cellHeight;
}
return cellHeight;
}
else
{
int cellHeight = 0;
if ([indexPath section] == 0)
{
cellHeight = 24;
settingsTable.rowHeight = cellHeight;
}
else if ([indexPath section] == 1)
{
cellHeight = 40;
settingsTable.rowHeight = cellHeight;
}
return cellHeight;
}
return 0;
}
To have the dynamic cell height as the text of Label increases, you first need to calculate height,that the text gonna use in -heightForRowAtIndexPath delegate method and return it with the added heights of other lables,images (max height of text+height of other static componenets) and use same height in cell creation.
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f
#define CELL_CONTENT_MARGIN 10.0f
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (indexPath.row == 2) { // the cell you want to be dynamic
NSString *text = dynamic text for your label;
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}
else {
return 44; // return normal cell height
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UILabel *label;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] ;
}
label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 280, 34)];
[label setNumberOfLines:2];
label.backgroundColor = [UIColor clearColor];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
label.adjustsFontSizeToFitWidth = NO;
[[cell contentView] addSubview:label];
NSString *text = dynamic text fro your label;
[label setText:text];
if (indexPath.row == 2) {// the cell which needs to be dynamic
[label setNumberOfLines:0];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
}
return cell;
}

Resources