1

I have a Storyboard which has a simple view hierarchy:

- View (has top/bottom constraints relative to safeArea >= 30, centerY)
   - Label (has height/top(SuperView)/bottom(TextField) constraints)
   - TextField (has height/top(Label)/bottom(TableView) constraints)
   - TableView (has height >= 0, top(TextField)/bottom(Superview) constraints)

Inside the UITableViewDelegate (cellForRowAt):

tableView.setNeedsLayout()
tableView.layoutIfNeeded()

The behaviour I wish to achieve is to have the TableView and the parent View grow as new records are added to it. However, the parent view should not exceed its top/bottom constraints relative to the safe area.

All the elements have height constrains and spacing explicitly set, except for the table view (which has height >= 0). As well, the parent's view content hugging priority is 250 and the tableview compression resistance is 750. I thought that fixing the height constraints and spacing between elements would allow the tableview to grow up to some point because the content compression resistance is higher for the top/bottom safe area constraints than it is for the TableView.

However, XCode is forcing me to set a height or a Y position constraint for the parent view. I can't do that because then the view cannot grow automatically.

I would prefer to stick with AutoLayout and wondering if anyone has an idea or resource on how to do this.

Vlad
  • 1,889
  • 17
  • 33

1 Answers1

3

Table views do not automatically set their height based on the number of rows.

You can use this custom table view class (from https://stackoverflow.com/a/48623673/6257435):

final class ContentSizedTableView: UITableView {
    override var contentSize:CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
}

This will "auto-size" your table view whenever the content size changes. To use it, add a table view and set its class to ContentSizedTableView.

  • Constrain the top, leading and trailing as desired.
  • Constrain the bottom to >= 0 to the bottom of the superview (or >= 8 if you want it to stop 8-pts from the bottom, or whatever value you want for your layout).
  • Give it a height constraint - doesn't really matter what, but using a value such as 100 let's you see it as you work with the layout.
  • Then edit that height constraint and check the Placeholder - Remove at build time checkbox.

The table view's height constraint will be removed when you run the app, and the ContentSizedTableView will automatically grow until it reaches the bottom constraint.

DonMag
  • 69,424
  • 5
  • 50
  • 86
  • Thank you, this works well. Is there a way to animate the parent view expadning when the table view size increases? – Vlad Apr 03 '19 at 18:43