I am building a comments feature using a UITableView with dynamic cell heights. I am using the Cartography framework to set the constraints of the contents of each cell programmatically, as this table view is not setup within the storyboard.
I have a problem with the comment label overlapping cells below it. Cells that have a short comment string are looking good, here's an example SS:
I have set tableView.estimatedRowHeight = 60
, cells are clipsToBounds = false
and
func tableView(_: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
UITableView.automaticDimension
}
Here are the constraints that I have set using the Cartography framework for the different subviews of the Cell:
// User Image View
constrain(self, userImageView) {
$1.height == 36.0
$1.width == 36.0
$1.left == $0.left + 16.0
$1.top == $0.top + 12.0
$1.bottom == $0.bottom - 12.0 ~ UILayoutPriority(500)
}
// Comment Label
constrain(self, commentLabel, userImageView) {
$1.top == $2.top - 6.0
$1.right == $0.right - (18.0 + Geometry.likeButtonWidth)
$1.left == $2.right + Geometry.messageLabelLeftOffset
}
// Bottom view - ( comment_time / LikeCount / Reply )
constrain(self.contentView, messageLabel, bottomView, userImageView) { contentView, msgLabel, bottomView, userImageView in
bottomView.top == msgLabel.bottom
bottomView.right == msgLabel.rightMargin
bottomView.left == userImageView.right + Geometry.messageLabelLeftOffset
// contentView.bottom == bottomView.bottom // very tall cell is overlapping cells below with this line
// contentView.height == msgLabel.height + 20 // cell is twice as tall, leaving large empty gap, but not overlapping
}
The comment label has no bottom constraint set.
The bottonView has it's top set to the comment label's bottom, with no bottom constraint either. I figured this allows for the dynamic height to work. Using neither of the commented out constraints above in bottomView's constrain, it is still overlapping. I understand the overlap is caused by clipsToBounds on the cell being set to false, so the cell's height is the problem.
This is how that looks:
How do I get the cells height to fit the content?
So I realized all constraints needed to use the cell's self.contentView
instead of just self
, I had previously tried this and it didn't render correctly but that was because not all vertical constraints were present as you could see above. So this is how it should have been:
// User Image View
constrain(self.contentView, userImageView) {
$1.height == 36.0
$1.width == 36.0
$1.left == $0.left + 16.0
$1.top == $0.top + 12.0
//$1.bottom == $0.bottom - 12.0 ~ UILayoutPriority(500) removed this
}
// Comment Label
constrain(self.contentView, commentLabel, userImageView, bottomView) {
$1.top == $2.top - 6.0
$1.right == $0.right - (18.0 + Geometry.likeButtonWidth)
$1.left == $2.right + Geometry.messageLabelLeftOffset
$1.bottom == $3.top
}
// Bottom view - ( comment_time / LikeCount / Reply )
constrain(self.contentView, messageLabel, bottomView, userImageView) { contentView, msgLabel, bottomView, userImageView in
bottomView.top == msgLabel.bottom
bottomView.right == msgLabel.rightMargin
bottomView.left == userImageView.right + Geometry.messageLabelLeftOffset
bottomView.bottom == contentView.bottom
}