问题
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?
回答1:
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.
回答2:
For me it took a combination of several things.
- Besides setting the content hugging and resistance correct
- I had to make a subclass of UILabel to handle the preferredMaxLayoutWidth of the label
- and correct a bug in the intrinsicContentSize as well
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:
- Preferred for content hugging and resistance: https://stackoverflow.com/a/16281229/1840269
- Description of the preferredMaxLayoutWidth manipulation: https://www.objc.io/issues/3-views/advanced-auto-layout-toolbox/
- Inspiration for the UILabel subclass with the intrinsicContentSize fix: https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8/issues/7
回答3:
For me setting content hugging priority and content compression resistance priority lower to one of the element worked just as expected.
来源:https://stackoverflow.com/questions/26055887/ios-7-8-uitableview-cell-two-uilabels-with-dynamic-height-with-auto-layout-for