I'm having a hard time trying to get a table view with dynamically sized cells to be layed out well under iOS 7 and 8. I can't detail all the differences that are to find (in the means of "ways of broken layouts") between iOS 7 and 8 which can be produced using the different "tweaks", "workarounds" and whatever I've found here and elsewhere. But in the end either on iOS 7 or on iOS 8 (if not both) some or all cell's content is misaligned because the layout system "breaks" one of the custom constraints to "recover".
Basically I have three different types of content. And as I show these contents not only in the aforesaid table view, I wrapped the contents in three subclasses of UIView
. Let's call them SummaryView
s
For the table view then I created three subclasses of UITableViewCell
of which each adds the according SummaryView
to its contentView
and sets self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
. On updateViewConstraints
I generally remove all "my" constraints that might have been added previously and do...
- (void)updateConstraints
{
// ...removed custom constraints before
NSDictionary *views = NSDictionaryOfVariableBindings(_summaryView);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_summaryView]-|"
options:0
metrics:nil
views:views]
toView:self.contentView];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_summaryView]-|"
options:0
metrics:nil
views:views]
toView:self.contentView];
[super updateConstraints];
}
In tableView:estimatedHeightForRowAtIndexPath:
I return a static estimate depending on the content's type.
In tableView:heightForRowAtIndexPath:
I use "prototype" cells in the manner of...
// ..set content on prototype cell before
[prototypeCell setNeedsUpdateConstraints];
[prototypeCell layoutIfNeeded];
CGSize size = [prototypeCell systemLayoutSizeFittingSize:UILayoutFittingExpandedSize];
return size.height;
Here usually the debugger breaks on UIViewAlertForUnsatisfiableConstraints
(on [prototypeCell layoutIfNeeded]
) with <NSLayoutConstraint:0x17409f180 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x17019f070(44)]>
conflicting with the rest of the constraints.
So I tried...
- Setting
tableView.rowHeight = UITableViewAutomaticDimension
in table view'sviewDidLoad
- Not implementing
tableView:estimatedHeightForRowAtIndexPath:
Using...
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1) { cell.contentView.frame = cell.bounds; cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; }
...before applying cell's content and calculating its layout
- Doing
self.contentView.bounds = CGRectMake(0.0, 0.0, 1000, 1000);
upon cell initialization - Probably other things which, right now, I can't remember as I'm on this for more or less two days now.
It's always the same, if I achieve a variant which doesn't complain about unsatisfiable constraints, the layout is usually messed up nevertheless. And although I get the table view not to set the "default" <NSLayoutConstraint:0x17409f180 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x17019f070(44)]>
constraint, the constraint set instead (on basis of the height returned by tableView:heightForRowAtIndexPath:
) neither suits the layout system.
This post is kind of a last resort. I know that without the concrete view classes' constraints you can't re-check them. But as I'm able to use these views's outside of a table view without problems, it shouldn't be a subview's constraint's problem.
I think I will have fall back to calculate the sizes of all view elements manually (on basis of [UIScreen mainScreen].bounds
) and set them directly (as widths and heights) to all subviews. So I'm able to get the concrete height of a cell and can set the contentView
's frame manually. Quite a pity as it messes up the layout code remarkably....
Best regards, gabriel