如何根据文本高度动态调整UITableViewCell的行高?
UITableView动态行高实现方案
针对你需要的顶部、底部区域固定60高度,中间评论区随文本动态调整的需求,提供两种实现方式,优先推荐自动布局+系统自动行高的方案,更简洁可靠:
方案一:自动布局+系统自动行高(推荐)
1. 配置UITableView
在viewDidLoad中设置自动行高和预估高度:
override func viewDidLoad() { super.viewDidLoad() tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 200 // 预估高度可根据实际情况调整,优化滚动性能 }
移除你之前写的固定返回400的heightForRowAt方法。
2. 配置TableViewCell的约束和标签属性
- 约束设置(在XIB/Storyboard中完成):
- 顶部用户名区域(绿红部分):顶部对齐
contentView.top,左右对齐contentView,高度固定60 - 中间评论标签(蓝色区域):顶部对齐顶部区域底部,左右对齐
contentView(注意设置左右边距,比如各10),底部对齐底部点赞区域顶部 - 底部点赞区域(黄色部分):顶部对齐评论标签底部,左右对齐
contentView,高度固定60,底部对齐contentView.bottom
- 顶部用户名区域(绿红部分):顶部对齐
- 评论标签属性设置:
在cell的awakeFromNib中或XIB/Storyboard里设置:userComment.numberOfLines = 0 // 允许多行 userComment.lineBreakMode = .byWordWrapping // 按单词换行
这样系统会根据自动布局约束,自动计算每行的高度,无需手动计算。
方案二:手动计算高度(适配你的原需求)
如果一定要在heightForRowAt中返回60+60+动态标签高度,可以通过文本尺寸计算实现:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let video = table[indexPath.row] guard let commentText = video.userComment else { return 120 } // 无文本时返回固定高度 // 计算评论标签的可用宽度(需和cell中标签实际宽度一致,这里假设左右边距各10) let commentWidth = tableView.bounds.width - 20 // 匹配cell中评论标签的字体 let commentFont = UIFont.systemFont(ofSize: 17) // 计算文本高度 let textSize = commentText.boundingRect( with: CGSize(width: commentWidth, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: [.font: commentFont], context: nil ).size // 向上取整避免高度不足 let commentHeight = ceil(textSize.height) return 60 + 60 + commentHeight }
同时要确保cell中评论标签的numberOfLines设为0,且宽度约束和计算时的commentWidth一致。
为什么之前sizeToFit返回18?
在awakeFromNib调用时,cell还未填充数据,评论标签的文本为空,且此时标签的宽度还未被布局引擎确定,所以sizeToFit计算的是单行空文本的默认高度(约18),无法得到真实的多行文本高度。
内容的提问来源于stack exchange,提问作者submariner
相关产品推荐
相关产品推荐

