I have a UITableView
with cells that have a fixed height of 100 points. The cells are created in a xib file that uses 3 constraints to pin a UILabel
to
Since you're constraining the label's width
, the intrinsicContentSize
honors that width
and adjusts the height
. And this sets up a chicken and egg problem:
intrinsicContentSize
intrinsicContentSize
depends on the label's width
width
depends on the cell's Auto Layout resultSo what happens is that the cell's layout is only calculated once in which (2) is based on the static width in the XIB file and this results in the wrong label height
.
You can solve this by iterating. That is, repeat the Auto Layout calculation after the label's width
has been set by the first calculation. Something like this in your custom cell will work:
- (void)drawRect:(CGRect)rect
{
CGSize size = self.myLabel.bounds.size;
// tell the label to size itself based on the current width
[self.myLabel sizeToFit];
if (!CGSizeEqualToSize(size, self.myLabel.bounds.size)) {
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
}
[super drawRect:rect];
}
original solution does not work reliably:
- (void)layoutSubviews
{
[super layoutSubviews];
// check for need to re-evaluate constraints on next run loop
// cycle after the layout has been finalized
dispatch_async(dispatch_get_main_queue(), ^{
CGSize size = self.myLabel.bounds.size;
// tell the label to size itself based on the current width
[self.myLabel sizeToFit];
if (!CGSizeEqualToSize(size, self.myLabel.bounds.size)) {
[self setNeedsUpdateConstraints];
[self updateConstraintsIfNeeded];
}
});
}