2
votes

I have a UITableView filled with one type of custom UITableViewCell. Each cell contains a title (UILabel), subtitle (UILabel), and thumbnail (UIImageView), as shown below.

prototype cell visual

The widths of all three subviews are fixed, but only the subtitle label has a fixed height. The title label's height is dynamic according to the amount of text. I have set the title label's numberOfLines to 0 to reflect this.

My objective: The height of the cell should be determined by the height of the title label. In other words, the cell height should be the sum of the two labels' heights plus the three vertical padding gaps. The image height should be set to the resulting height of the cell.

My current implementation: I have set the following autolayout constraints:

  • Thumbnail is pegged to superview on top, left and bottom
  • Thumbnails width is proportional to superview width by a multiple of 0.2
  • Thumbnail is pegged on its right side to title and subtitle (trailing space = 8)
  • Title is pegged to superview on top and right (trailing space = 8)
  • Title is pegged on its bottom to subtitle (trailing space = 8)
  • Title height is greater than or equal to 24
  • Subtitle is pegged to superview on right and bottom (trailing space = 8)
  • Subtitle height is equal to 20

Additionally:

  • Title numberOfLines = 0
  • Thumbnail contentMode = Aspect Fill
  • Thumbnail clipToBounds = true

The problem: The image height does not respect the height of the labels, so the height of the cell is set to the full height of the image and the title label is stretched vertically. This is understandable given the constraints I have used, but is not what I want to happen.

My question: How do I constrain the UIImageView's height to respect the cell height (determined by dynamic label height), instead of having the cell height respect the UIImageView height?

My Environment:

  • Xcode 10
  • iOS 11 & 12
  • Swift 4.2
2

2 Answers

7
votes

Try setting thumbnail vertical compression resistance lower than title vertical hugging priority. In code it'll look like this:

    thumbnail.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
    titleLabel.setContentHuggingPriority(.required, for: .vertical)
2
votes

I'll explain the vertical constraints to make this possible.

  • Pin the top of the label to the contentView with enough padding so that image view stays inside it.
  • Pin the top of the subtitleLabel to the bottom of the titleLabel.
  • Pin the bottom of the subtitle similarly to the bottom of the contentView, so that the image view stays inside it.

Your cell now has a height based on the above constraints. Now you just have to make sure you place the image view inside this height.

  • Pin the top of the thumbnail to the top of the label, bottom to the bottom of the subtitle label.

Example:

  • titleLabel.top -> contentView.top + 10
  • subtitleLabel.top -> titleLabel.bottom + 5
  • subtitleLabel.bottom -> contentView.bottom - 10
  • imageView.top -> titleLabel.top - 5
  • imageView.bottom -> subtitleLabel.bottom + 5