9
votes

I have a table view with a bunch of cells (custom cell, which only has its content view).

In tableView:cellForRowAtIndexPath: I'm adding a predefined UIView (which has several subviews) to the content view of the custom cell. I set up all constraints for the UIView and its subviews before.

Last but not least, I set the vertical and horizontal constraints for the content view of my custom cell (superview) and the UIView, which was added before (subview).

The constraint strings look like this:

    H:|[view]|
    V:|[view]|

Unfortunately, I still get the default height for all table view cells. I'm wondering If there's a way to let auto layout do the calculation of the height automatically according to content size.

4
No. You need to implement tableView:heightForRowAtIndexPath and return a height or the default height of the cell will be used.Robotic Cat
Is there any way to let the the view decide which height it should get?Chrizzor
If you use custom UITableViewCells you could create a method in the subclass that returns the height for that cell and then call that method in tableView:heightForRowAtIndexPath. Obviously, try to make the calculation fast and efficient (possibly pre-calculate the result on any change and cache the result if the calculation is very complex).Robotic Cat
thanks for your answer. unfortunately calculating the cells content is no solution for me. the problem is, that i don't know what's inside the view.Chrizzor
Maybe in a future iOS version they'll update the way tableview cells work but (as of iOS 6) you need to mix both approaches. Good luck with the app.Robotic Cat

4 Answers

5
votes

Check out my detailed answer to this question here: https://stackoverflow.com/a/18746930/796419

It takes a bit of work to set up, but you can absolutely have Auto Layout constraints driving a completely dynamic table view without a single hardcoded height (and let the constraint solver do the heavy lifting and provide you with the row height).

2
votes

Auto Layout won't help with the cell height. You'll need to set that in tableView:heightForRowAtIndexPath. I guess you're probably asking this because your cell heights are variable, not fixed. i.e., they depend on the content.

To resolve that, pre-calculate the cell heights and store them in an array. Return the value for the appropriate indexPath in the tableView:heightForRowAtIndexPath method.

Be sure to calculate content sizes on the main thread, using sizeThatFits of UILabel classes and such like.

If your calculation is intensive, do the majority of it off main apart from the view related methods such as sizeThatFits.

0
votes

I solved the problem by using CGSize size = [view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; in tableView:heightForRowAtIndexPath:.

0
votes

To set automatic dimensions for 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)

Swift:

@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