Alex
Alex

Reputation: 5278

Incorrect UITableViewCell Height with Dynamic UILabels and Content Compression/Resistance

Building on Xcode 7.2.1, iOS 9.2

I have a UITableView with cells that have automatic height.

tableView.estimatedRowHeight = 80
tableView.rowHeight = UITableViewAutomaticDimension

The layout of the cells is as follows:

UITableViewCell
  contentView
  outerStackView - pinned to top, left, right, bottom edges of the contentView with autolayout
    leftColumnStackView - 38% of width of outerStackView
       topStackView
         label UILabel
         value UILabel
       bottomStackView
         label UILabel
         value UILabel
    middleColumnStackView - 38% of width of outerStackView
      ...
    rightColumnStackView - rest of the width of outerStackView
      ...

The cells have 6 label/value pairs in them -- [Label X: Value]. Each label/value pair is comprised of 2 UILabels, with their content hugging and content compressions resistance attributes set accordingly to give the desired look.

label.numberOfLines = 0
label.textAlignment = NSTextAlignment.Left
label.setContentCompressionResistancePriority(1000, forAxis: .Horizontal)
label.setContentHuggingPriority(1000, forAxis: .Horizontal)

value.numberOfLines = 0
value.setContentCompressionResistancePriority(500, forAxis: .Horizontal)
value.setContentHuggingPriority(500, forAxis: .Horizontal)

// there are 6 stack views, each containing a label/value pair
// the stack views are .Horizontal alignment, and pinned to the 
// columns they sit in
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(value)

However, sometimes the cell height properly measures itself, and other times adds a bunch of extra space (interesting enough, the extra space is always equal to the space that would be there if the content compression/hugging wasn't added to either label).

Here's the inconsistency that happens:

Sometimes it's right: enter image description here

Sometimes it's wrong: enter image description here

When I remove the content compression/resistance from the labels however, the cell is always the correct height, but looks like this: enter image description here

Anybody experienced similar? Have any suggestions?

Upvotes: 1

Views: 1695

Answers (1)

Alex
Alex

Reputation: 5278

Figured it out!

This ended up having to do with how the contentView of the cell was positioned using AutoLayout. Apparently, by default it was not laying out and calculating the position of its subviews correctly.

In my UITableViewCell subclass, I added the following to my init()

contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.leadingAnchor.constraintEqualToAnchor(leadingAnchor).active = true
contentView.trailingAnchor.constraintEqualToAnchor(trailingAnchor).active = true
contentView.topAnchor.constraintEqualToAnchor(topAnchor).active = true
contentView.bottomAnchor.constraintEqualToAnchor(bottomAnchor).active = true

By pinning the contentView to the cell, the issue of the inconsistent height assignment of that UITableViewCell went away, and the correct height was always displayed.

This has resulted in the contentView being stretched to all 4 edges, which does effect some other things (like the animation of when a UITableView has editing flipped to true), but for now I can work around those issues in other ways, since nothing is being calculated as wrong or is happening that's unexpected anymore.

Upvotes: 2

Related Questions