Cannot change frame of a UILabel in a UITableViewCell when first appearing (using Autolayout)

十年热恋 提交于 2019-12-10 12:57:22

问题


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

I create the prototype cell in cellForRowAtIndexPath like this:

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 the cell is displayed, layoutSubviews is called, but the descriptionLabel does not get resized. However, if I scroll down the table and back up again, the "reused" cell appears with the label correctly resized!

Why does it not work the first time the cell is displayed - and what do I need to do to fix it.

Thanks in advance!


回答1:


In xib, go to first tab, under Interface Builder Document , uncheck use Auto Layout box.




回答2:


It doesn't work because you are using auto layout. You need some auto layout way to achieve this.

Here's the solution.

Step 1 :

Have the UILabel Pinned to Top and Bottom of the UITableViewCell. You can achieve this through the Interface Builder by having Vertical Constraint on UILabel from top and bottom of the cell. This will make the UILabel increase in height if the cell's height increase or vice versa.

Step 2:

In your UIViewController in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath method 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 return the textFrame.size.height + padding if present.

Step 3 :

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




回答3:


After retrieving all data from server you can get height of that 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 have given description of measureHeightForText:. This logic is working 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 size of your label according it. This is working fine for me. I am using it.




回答4:


Because when layoutSubviews is called your descriptionLabel's text is not set yet. And when you scroll, the text is set. So it is correct now.

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;



回答5:


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;



回答6:


You can use below code:

//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;



回答7:


If your requirement is dynamically changing label height mean follow the below link. When we need to change height of label we need to change the row height also:

Resizing UILabel not quite working




回答8:


Use below code for dynamic height set in 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;
}



回答9:


If you are using autolayout, modifying the frame will have no effect.

Instead, you should modify the constraints.



来源:https://stackoverflow.com/questions/20996196/cannot-change-frame-of-a-uilabel-in-a-uitableviewcell-when-first-appearing-usin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!