简体   繁体   中英

iOS table view cell auto height with custom subview

I need pretty simple thing - table cells which automatically detect their own height. There are a lot of examples out there, which basically say "set couple of flags and values on your table and use autolayout in your cell". My case is a bit special - I load the content of the cell from a separate XIB file which is a plain UIView. The first problem comes already when I create that XIB file in interface builder - I don't know how to make it's height to "calculate" according to constraints that I specify. I am always getting IB errors unless I switch to "Freeform" and resize the view to the height matching my constraints. If I don't do that, I will get the following errors:

在此处输入图片说明

In the above example I just need a view which height will be 32 (image height) + 2 * 16 (vertical distance constraints of image from parent's top and bottom) plus the margins. Resizing the freeform view in IB until the errors disappear seems like a dirty hack to me, and it is actually not auto layout. As a next step, I define a cell class, where I put this xib view, something like this (sorry for objc code, almost done porting the project to swift) :

- (void)awakeFromNib {
    [super awakeFromNib];

    [[NSBundle mainBundle] loadNibNamed:@"CellContent" owner:self options:nil];

    // self.content is an outlet which gets the root of the XIB on load
    [self.contentView addSubview:self.content];

    self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.contentView.leftAnchor constraintEqualToAnchor:self.content.leftAnchor].active = YES;
    [self.contentView.rightAnchor constraintEqualToAnchor:self.content.rightAnchor].active = YES;
    [self.contentView.topAnchor constraintEqualToAnchor:self.content.topAnchor].active = YES;
    [self.contentView.bottomAnchor constraintEqualToAnchor:self.content.bottomAnchor].active = YES;
}

As you might guess, when I run this the cell height is the big freeform one, like in the IB of the content XIB, so no auto layout. It seems like the freeform height is even added as another constraint and there is a constraint conflict which results in some of them being broken at runtime.

Let me know how can I fix this, easily create content views for my cells which have auto heights and which I can embed in my cells to benefit the tableView.rowHeight = UITableViewAutomaticDimension magic?

Maybe you forgot to set the Content Hugging Priority and Content Compression Resistence Priority of the Labels. enter image description here

  1. Make sure UILabel has multiline property . So , Set 0 for Line Property at Attribute Inspector .
  2. Make sure that UILabel Auto-Layout is properly relative to Left-Right-Top-Bottom .
  3. Apply these delegate Functions :

     -(CGFloat) tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; } 

I found what was my problem. Actually, there were conflicts with constraints added because of autoresizing. So I changed this line (from the question above):

self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

to:

self.content.translatesAutoresizingMaskIntoConstraints = NO;

Stupid mistake, the translatesAutoresizingMaskIntoConstraints flag should be disabled for the child view after adding, not for the parent view, as I incorrectly did. After that the magic with cell auto height detection started working like charm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM