I have a tableview cell whose view is loaded from an nib and whose subviews are constrained using AutoLayout. I'm using the self-sizing cells feature of iOS 8. On first display, the cells look like this:
The margin between the green view and the blue & gray views is larger than I expect. If I scroll down the view so more cells are created, or if I call reloadData on the tableview, then I get the correct result:
It is as if the cells subviews are not correctly sized until the 2nd layout pass. How can I get around this? I've seen some posts that suggest setting setPreferredMaxLayoutWidth
in layoutSubviews
, like so:
-(void)layoutSubviews
{
[super layoutSubviews];
[self.redLabel setPreferredMaxLayoutWidth:[self.titleLabel bounds].size.width];
[self.greenLabel setPreferredMaxLayoutWidth:[self.extendedLabel bounds].size.width];
[self.blueLabel setPreferredMaxLayoutWidth:[self.dateLabel bounds].size.width];
[self.grayLabel setPreferredMaxLayoutWidth:[self.tagsLabel bounds].size.width];
[super layoutSubviews];
}
...but it seems to have no effect.
There doesn't appear to be any ambiguity in my constraints, but since they are set up in a .nib I'm not sure how to post them here.
Edit 1:
So I have the top space of the blue/gray views set to be >= the bottom of the green view, +3. Which is in effect what I get, since the space is greater.
However, if I set the relationship to be ==, I get a different visual error, where the red label is incorrectly sized for the amount of text it contains:
Edit 2:
Not sure if I should start a new question, but it's the same problem.
Still having recurring problems with the layout as in Edit 1. Apart from the visual problem, it causes a horrible effect when a single cell changes in my tableview. The whole list will appear to collapse and reload. Additionally, I get the following autolayout error logged:
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x797c5bc0 UITableViewCellContentView:0x7970adc0.(null) == UILabel:0x79707cf0.trailing + 6>",
"<NSLayoutConstraint:0x7977b560 UILabel:0x79707cf0.leading == UITableViewCellContentView:0x7970adc0.(null) + 6>",
"<NSLayoutConstraint:0x7970a700 UITableViewCellContentView:0x7970adc0.width ==>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x797c5bc0 UITableViewCellContentView:0x7970adc0.(null) == UILabel:0x79707cf0.trailing + 6>
Where the UILabel referred to is the longer, green label. It seems like it can't reconcile the leading and trailing constraints with whatever width the cell has, as if the cell is smaller than 12 points overall. Logging out the width seems to always result in 320, however.