Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically-sized UITableView in UIScrollView with Auto-Layout

There are a million questions about auto-layout and UIScrollViews, but I think this is something different.

I have a construct that looks like this:

Resizing Example

The white background is a UIView which acts as a container within a UIScrollView (the typical setup for get a scroll view to build its own content size so it scrolls properly based on the container view).

TableView 1 and TableView 2 need to have their heights be dynamic. I don't want them scrolling, so I need to set their frame height equal to their content height.

I have IBOutlets for the height constraint for each of these, and can adjust them with no problem.

The issue arises when I try to adjust the height of the container view. Ultimately, I would like to not have to mess with it and let that view resize automatically based on its content, but that does not seem to be working (if I leave off the height of the container view, I get warnings/errors in IB about the constraints).

If I create an outlet to the container view's height constraint and set it, I get an assert fail:

*** Assertion failure in -[UIView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8803

I am doing the constraint adjusting in viewDidLayoutSubviews like this:

- (void)viewDidLayoutSubviews {
    self.orderItemTableViewHeightConstraint.constant = self.orderItemTableView.contentSize.height - [self tableView:self.orderItemTableView heightForHeaderInSection:0];
    self.shippingOptionTableViewHeightConstraint.constant = self.shippingMethodTableView.contentSize.height;
    self.scrollViewContainerViewHeightConstraint.constant = self.cardInfoLabel.$bottom + 60;
}

I believe the problem is setting the container view's height constraint is causing some recursion or something...

The questions:

  1. IS there a way to let the container view's height be fluid based on its content in this situation?
  2. If not, how do I handle this programmatically? Am I altering the constraints in the wrong place or something?

Thanks for any input!

like image 725
Raconteur Avatar asked Feb 13 '23 17:02

Raconteur


1 Answers

Ok, well, just shotgunning code here, but after much trial and error, this seems to resolve the assert failure and gives the desired result:

- (void)viewDidLayoutSubviews {
    self.orderItemTableViewHeightConstraint.constant = self.orderItemTableView.contentSize.height - [self tableView:self.orderItemTableView heightForHeaderInSection:0];
    self.shippingOptionTableViewHeightConstraint.constant = self.shippingMethodTableView.contentSize.height;

    [self.view layoutIfNeeded];

    self.scrollViewContainerViewHeightConstraint.constant = self.cardInfoLabel.$bottom + 60;

    [self.view layoutIfNeeded];
}

Would really like to have this more dynamic, but will take the win at this point in the game!

Hope this helps someone else.

like image 94
Raconteur Avatar answered May 07 '23 03:05

Raconteur