I am trying to create a UITableView whose cell's heights are sized according to the amount of text being displayed. This seemed simple enough, as heightForRowAtIndexPath
is available and I can get the required size needed for the UILabel
using the code shown below. However, this method is called before cellForRowAtIndexPath
so I cannot size based on the content in the cell, which seems a very strange choice to me. What is the "best practice" way to dynamically size the height of the cells based on content?
In addition, why did Apple not have the heightForRowAtIndexPath
method be called after cellForRowAtIndexPath
?
I am using the following in cellForRowAtIndexPath
to determine the required height for my label, but I'm not sure how to move this to heightForRowAtIndexPath
since dequeReusableCellWithIdentifier
cannot be called in the method (as far as I know):
func getRequiredLabelHeight(label: UILabel, text: String, font: UIFont) -> CGFloat {
label.numberOfLines = 0
label.lineBreakMode = .ByWordWrapping
label.font = font
label.text = text
label.sizeToFit()
return label.frame.height
}
I also know that I want the following to be my cell height, since I want the cell size to increase from the initial size (hinging on a 1 line label) based on the new label size (which can be any arbitrary length of lines)
self.cellHeight = getRequiredLabelHeight(commentCell.commentTextLabel, text: allComments![indexPath.row].text, font: UIFont(name: "Avenir", size: 16.0)!) + commentCell.bounds.height - commentCell.commentTextLabel.bounds.height
Thanks!
EDIT
My question does NOT pertain to resizing the label. The code I have provided does that. The issue is that the cell height is not constant; it varies throughout the table based on the content, so I can't use a static tableview.rowHeight
. Since I cannot resize the cell height from cellForRowAtIndexPath
, my content will not fit in the cell. For example, here is my cellForRowAtIndexPath
(in a nutshell):
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let commentCell: CommentTableViewCell = tableView.dequeueReusableCellWithIdentifier("commentTableViewCell", forIndexPath: indexPath)
as! CommentTableViewCell
commentCell.commentTextLabel.textColor = Utils.hatchliTextDark
commentCell.commentTextLabel.font = UIFont(name: "Avenir", size: 16)
self.cellHeight = getRequiredLabelHeight(commentCell.commentTextLabel, text: allComments![indexPath.row].text, font: UIFont(name: "Avenir", size: 16.0)!) + commentCell.bounds.height - commentCell.commentTextLabel.bounds.height
commentCell.commentTextLabel.frame = CGRectMake(commentCell.commentTextLabel.frame.origin.x, commentCell.commentTextLabel.frame.origin.y, commentCell.commentTextLabel.frame.width, self.cellHeight)
commentCell.handleTextLabel.text = String(allComments![indexPath.row].creatorHandle)
commentCell.votesTextLabel.text = String(allComments![indexPath.row].votes)
commentCell.commentTextLabel.text = allComments![indexPath.row].text
commentCell.setMargin()
return commentCell
}
So, if the frame of the UILabel becomes larger than tableview.rowHeight
, it will not appear. Thus, the row height needs to be resized on a per cell basis from heightForRowAtIndexPath
(I assume)