So I am able to set up dynamic height sizing with auto layout when I have only one label that changes the height based on the length of the string. My problem is that if I add another UILabel that should do the same, things don't work out.
I am setting both the Content Hugging priority and the Compression Resistance to 1000 for both == I get warnings of ambiguity
If I set the Content Hugging (Vertical) for the second UILabel to 999 or 250 then it works great but only if the second label has 2 or more line. If the second label is blank or has only one line, the heightForRowAtIndexPath systemLayoutSizeFittingSize:UILayoutFittingCompressedSize height returns large values, and the cells have large blank spaces.
I also played around with the Intrinsic Size: Default or Placeholder(with couple of heights and widths) but it does not help either.
Anyone any suggestions what can be done?
Image view without an image selected has no intrinsic content size, hence we need to set an explicit height constraint for it. The key to achieve dynamic height table view cell is to let Auto Layout know how to calculate the height of the cell.
A view that presents data using rows in a single column.
I got it working finally. The solution was for me to explicitly set the Preferred Width to the current frame width. So basically checking the Explicit check mark in the Label > Preferred Width in the Size Inspector.
ref: http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout download the sample code and see the storyboard setup.
For me it took a combination of several things.
The UILabel subclass ended up looking like this:
@implementation LabelDynamicHeight
- (void)layoutSubviews
{
[super layoutSubviews];
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
if (self.numberOfLines == 0)
{
CGFloat boundsWidth = CGRectGetWidth(bounds);
if (self.preferredMaxLayoutWidth != boundsWidth)
{
self.preferredMaxLayoutWidth = boundsWidth;
[self setNeedsUpdateConstraints];
}
}
}
- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
if (self.numberOfLines == 0)
{
// There's a bug where intrinsic content size may be 1 point too short
size.height += 1;
}
return size;
}
@end
Besides this calling layoutIfNeeded on the cell before getting the height in tableView heightForRowAtIndexPath:
made the constraints to be ready before using the systemLayoutSizeFittingSize:
method on the contentView. Looking like this:
- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ...;
CGFloat height = cell.frame.size.height;
if (cell.dynamicHeight)
{
// https://stackoverflow.com/a/26351692/1840269
[cell layoutIfNeeded];
height = cell.frame.size.height;
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
if (size.height > height)
height = size.height;
}
return height;
}
References:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With