質問

I designed a custom UITableViewCell by adding some subviews in the cell's contentView, I also added some auto layout constraints between the contentView and the subviews.

But when I debug the app, Xcode tells me that there is a constraint conflict. In the list of constraint, there is one NSAutoresizingMaskLayoutLayoutConstraint that limits the cell height to be 43, so Xcode break the constraint of my subview height and 'compress' it.

I have tried:

  1. In Interface builder, uncheck the "autoreize subviews" checkbox. Doesn't work.

  2. In code, cell.contentView.translatesAutoResizingMaskIntoConstraints = NO. This causes the app to crash with an exception: "Auto Layout still required after executing -layoutSubviews". I have tried every proposed solution in this question: "Auto Layout still required after executing -layoutSubviews" with UITableViewCell subclass None of them work for me.

So I guess I can only let the cell do its autoresizing thing, and remove the auto resizing constraint in code. How should I do it without breaking things?

EDIT: Or, from another perspective, how I can make the tableViewCell height flexible (changes with subview height and constraints)? In IB, I have to set its height, right?

役に立ちましたか?

解決

You DON'T need to set cell.contentView.translatesAutoResizingMaskIntoConstraints = NO

In order to get the flexible height in UITableViewCells in autolayout you need to manually compute for the height in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

Yes this tedious, but there is no other way. To calculate the height automatically you need to fulfill two conditions in your UITableViewCell:

  1. You must make sure all your subviews have translatesAutoResizingMaskIntoConstraints=NO
  2. Your cell subview's constraints must be pushing against the top and bottom edges of the UITableViewCell.

Then in your - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath, You need to recreate that cell for the specific indexPath and compute the height manually for that cell.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath 
*)indexPath
{

 //Configure cell subviews and constraints
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
 [self configureCell:cell forIndexPath:indexPath];

 //Trigger a layout pass on the cell so that it will resolve all the constraints.
 [cell setNeedsLayout];
 [cell layoutIfNeeded];

 //Compute the correct size of the cell and get the height. This is where the magic happens.
 CGFloat height = [cartItemCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    height += 1.0f

 return height;

}

Take note that systemLayoutSizeFittingSize is wonky with UITextViews. In that case you have to compute the height of the entire cell manually using another way. There are also some performance optimizations you can do by caching the height per indexPath.

This blog post has a a more detailed description on what to do but the gist is essentially what I mentioned above. : http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights

他のヒント

I have created some sample code for dynamic tableview cell height with auto layout. You can download the project using following link.

DynamicTableViewCellHeight

I hope this will help you.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top