Unable to change UILabel frame in UITableViewCell on first appearance (using Autolayout)

I have a cell prototype inside my UITableView that contains a UILabel . I want to dynamically resize the label (and cell) depending on the size of the text in the label.

I create a prototype cell in cellForRowAtIndexPath as follows:

 static NSString *CellIdentifier = @"ProgramDetailCell"; ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.descriptionLabel.text = self.program.subtitle; return cell; 

Then my ProgramDetailCell has the following implementation:

 @implementation ProgramDetailCell - (void)layoutSubviews { [super layoutSubviews]; [self.descriptionLabel sizeToFit]; } @end 

The first time a cell is layoutSubviews , layoutSubviews is layoutSubviews , but descriptionLabel does not change. However, if I scroll down the table and back up again, the "reused" cell is displayed with the label correctly changed!

Why it doesnโ€™t work on the first display of the cell - and what I need to do to fix it.

Thanks in advance!

+7
ios objective-c uitableview autolayout layoutsubviews
source share
9 answers

In xib, go to the first tab, in the "Interface Document" section, uncheck the "Auto Layout" box.

+9
source share

This does not work because you are using auto layout . To do this, you need an auto layout method.

Here is the solution.

Step 1:

Connect the UILabel to the top and bottom of the UITableViewCell . You can achieve this with Interface Builder by having a Vertical Constraint on a UILabel from top and bottom cells. This will increase the height of the UILabel as the cell height increases, or vice versa.

Step 2:

In your UIViewController method in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath calculate the size of the UITableViewCell .

You can calculate it using:

  CGRect textFrame = [YourText boundingRectWithSize:CGSizeMake(width of the label, FLT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:Your Font} context:nil]; 

now indent textFrame.size.height +, if any.

Step 3:

You will achieve what you want - "dynamically change the size of the label (and cell) depending on the size of the text in the label" after compiling and running even for the first time.

+4
source share

After extracting all the data from the server, you can get the height of this UILabel using this method.

 CGSize maximumSize = CGSizeMake(210, 9999); for (int i = 0; i < [_arrProductList count]; i++) { float row_height = 0.0f; ProductInformation *product_obj = [_arrProductList objectAtIndex:i]; CGSize desc_size = [self measureHeightForText:product_obj.product_desc forFont: [UIFont systemFontOfSize:14] forSize:maximumSize]; row_height = row_height + desc_size.height; // [_arrRowHeights addObject:[NSString stringWithFormat:@"%f", row_height]]; You can take it into array. } [tableView reloadData]; 

And here I gave a description of measureHeightForText: This logic works in all iOS5 , iOS6 , iOS7 .

 -(CGSize)measureHeightForText:(NSString *)strText forFont:(UIFont *)font forSize:(CGSize)size{ if (!testingLabel) { testingLabel = [[UILabel alloc] init]; // testingLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; testingLabel.text = @""; testingLabel.numberOfLines = 0; } testingLabel.text =strText; testingLabel.font = font; CGSize expectedSize = [testingLabel sizeThatFits:size]; return expectedSize; } 

And then update the size of your shortcut to fit it. This works great for me. I use it.

+2
source share

Because when layoutSubviews is called your descriptionLabel text, it is not set yet. And when you scroll the text, it is set. So now itโ€™s right.

I suggest you call sizeToFit after you set the text.

 static NSString *CellIdentifier = @"ProgramDetailCell"; ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.descriptionLabel.text = self.program.subtitle; [cell.descriptionLabel sizeToFit]; return cell; 
+1
source share

Call this in heightForRowAtIndexPath and manually calculate the height

 static NSString *CellIdentifier = @"ProgramDetailCell"; ProgramDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; cell.descriptionLabel.text = self.program.subtitle; [cell.descriptionLabel sizeToFit]; return cell.descriptionLabel.frame.size.height+cell.descriptionLabel.frame.origin.y; 
+1
source share

You can use the code 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; 
+1
source share

If your requirement dynamically changes the height of the inscription, follow the link below. When we need to change the height of the label, we also need to change the height of the line:

Resizing UILabel Doesn't Quite Work

+1
source share

Use the code below for the dynamic height set in the cell

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *messagetext=[NSString stringWithFormat:@"%@",[[arryStoryView objectAtIndex:indexPath.row] valueForKey:@"messagetext"]]; CGSize StoryTextSize= [messagetext sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; int TotalHeight; TotalHeight= StoryTextSize.height + 10; return TotalHeight; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell1"; UITableViewCell *cell=[tblSendMsg dequeueReusableCellWithIdentifier:CellIdentifier]; cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; NSString *storytext=[NSString stringWithFormat:@"%@",[[arryStoryView objectAtIndex:indexPath.row] valueForKey:@"storytext"]]; CGSize StoryTextSize = [storytext sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; lblStoryText.frame=CGRectMake(5, 25, [[UIScreen mainScreen] bounds].size.width-10, StoryTextSize.height+30); int nooflines=StoryTextSize.height/16; int i= StoryTextSize.height; if(i%16 !=0) { nooflines=nooflines+1; } lblStoryText.numberOfLines=nooflines; lblStoryText.font=[UIFont fontWithName:@"Georgia" size:17.0f]; lblStoryText.text=[NSString stringWithFormat:@"%@",storytext]; return cell; } 
0
source share

If you use autoplay, changing the frame will have no effect.

Instead, you should change the restrictions.

0
source share

All Articles