UITableViewCell + Dynamic Height + Auto Layout

8.4k views Asked by At

I came from this great answer:
Using Auto Layout in UITableView for dynamic cell layouts & variable row heights

I've implemented the things described in that answer but I'm facing with a little different scenario. I haven't one UILabel but instead I have a dynamic list of UILabels.

I've created an image showing some different cases of what the table view should look:

enter image description here

At the current state of the repo the cell doesn't grow vertically to fit the cell's contentView.


UPDATE

REPO: https://github.com/socksz/DynamicHeightCellAutoLayout

If you try to get the project from the repo and run it, you can see exactly what is the problem I'm referring. I can't get what is missing for let it works.

2

There are 2 answers

3
smileyborg On

The problem here is with the third party component you are using, FXLabel, not with any of the code around table views or Auto Layout in them. In order to support Auto Layout, custom subclasses of UIView must implement the -[intrinsicContentSize] method appropriately, and then call -[invalidateIntrinsicContentSize] when something changes it.

In this case, FXLabel appears to be relying on its superclass implementation (UILabel) for the above methods, and since UILabel was not designed to handle variable line spacing in the way that FXLabel implements it, it doesn't know the correct intrinsicContentSize to return, and therefore the Auto Layout calculations are wrong (in this case, since the intrinsic content size is too small). Check out the "Enabling Custom Views for Auto Layout" section of this excellent obcj.io article for more details.

Now the good news is that as of iOS 6, you should be able to accomplish this using an attributed string in a standard UILabel. Check out the Stack Overflow answer here.

If for some reason you really like FXLabel, perhaps you could open an issue on the GitHub project (or try and fix it yourself and submit a pull request).

0
Krunal On

To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.

  • Assign and implement dataSource and delegate
  • Assign UITableViewAutomaticDimension to rowHeight & estimatedRowHeight
  • Implement delegate/dataSource methods (i.e. heightForRowAt and return a value UITableViewAutomaticDimension to it)

-

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

For label instance in UITableviewCell

  • Set number of lines = 0 (& line break mode = truncate tail)
  • Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
  • Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.

enter image description here