I have a view controller which has a UITableView instance and uses auto layout constraints to render it. I would like to have variable cell heights in this table view. I do not want to calculate the cell height myself because I have a complex cell content composed of several labels and images that can vary from cell to cell. I do believe it is possible to let the auto-layout cell to resize itself so it contains all its subviews (i.e. using sizeToFit method of labels after assigning text to them?).
I have a custom cell class that uses visual constraints format of auto layout to position its subviews. I tried to incorporate the method proposed in here and its sample implementation here.
When I initialize the table view, I create an array with the equal length of my data rows and calculate each row's height by assigning values to a prototype cell of type MyCustomCell and retrieve its height using this
[cell systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height
and storing it in the heights array so to use it later in heightForRowAtIndexPath method of table view to retrieve the correct cell height for individual cells.
Doing all these, however, I end up with an unreadable exception NSInternalInconsistencyException in xCode with "Cannot find an outgoing row head for incoming head MyCustomCell:0xa8a1430.Width, which should never happen."
Here is the initialization of the subviews in my custom cell:
_titleLabel = [[UILabel alloc] init];
_titleLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
_titleLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
_titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:19];
_titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[self.contentView addSubview:_titleLabel];
_summaryLabel = [[UILabel alloc] init];
_summaryLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
_summaryLabel.backgroundColor = [UIColor clearColor];
_summaryLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
_summaryLabel.translatesAutoresizingMaskIntoConstraints = NO;
_summaryLabel.numberOfLines = 0;
_summaryLabel.preferredMaxLayoutWidth = 250.0f; // required for text wrapping
_summaryLabel.font = [UIFont fontWithName:@"Georgia" size:14];
_summaryLabel.lineBreakMode = NSLineBreakByWordWrapping;
[self.contentView addSubview:_summaryLabel];
_thumbnailView = [[UIImageView alloc] init];
_thumbnailView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:_thumbnailView];
and the constraints for my custom cell are as follow
NSDictionary *views = NSDictionaryOfVariableBindings(_titleLabel, _summaryLabel, _thumbnailView);
NSDictionary *metrics = @{@"margin": @"5"};
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView(<=60)]-(margin)-[_titleLabel]-(margin)-|"
options:0
metrics:metrics
views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_thumbnailView]-(margin)-|"
options:0
metrics:metrics
views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_titleLabel]-(0)-[_summaryLabel]"
options:0
metrics:metrics
views:views]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView]-(margin)-[_summaryLabel]-(margin)-|"
options:0
metrics:metrics
views:views]];