UITableView如何实现动态行高,适配UILabel内容与固定高度UIImageView
UITableView单元格动态高度适配方案
问题核心原因
你仅设置了自动高度属性,但未完成TableView预估行高配置、单元格约束逻辑,导致系统无法正确识别UILabel的自适应高度,只能以固定高度的UIImageView作为高度计算基准。
方案1:Auto Layout自动适配(推荐)
步骤1:配置TableView基础属性
在UIViewController的viewDidLoad方法中添加如下配置:
// 设置预估行高,可略大于图片固定高度70 tableView.estimatedRowHeight = 80 // 开启自动高度 tableView.rowHeight = UITableView.automaticDimension
注意:如果使用该方案,不需要额外实现heightForRowAt方法
步骤2:配置单元格约束
对自定义单元格内的控件添加如下约束:
- UIImageView约束:
- 固定高度为70,宽度按业务需求设置(如固定100、宽高比1:1均可)
- 左侧距离contentView左边缘为固定边距(如16pt)
- 顶部距离contentView顶部 ≥ 12pt,底部距离contentView底部 ≤ 12pt
- 可选添加垂直居中于contentView的约束,优先级设为999(避免高度差过大时触发约束警告)
- UILabel约束:
- 左侧距离UIImageView右边缘为固定边距(如12pt)
- 右侧距离contentView右边缘为固定边距(如16pt)
- 顶部距离contentView顶部 ≥ 12pt,底部距离contentView底部 ≤ 12pt
- 行数设置为0,支持多行展示
- 将UILabel垂直方向的抗压缩优先级设置为1000,避免长文本被系统压缩
配置完成后系统会自动取两个控件撑出的最大高度作为单元格高度,完全符合你的需求。
方案2:手动计算行高
如果你希望完全控制高度计算逻辑,可以直接在heightForRowAt方法中计算返回对应高度:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { // 1. 取当前行对应的文本内容 let contentText = yourDataSource[indexPath.row].content // 2. 计算UILabel的可用宽度:屏幕宽度 - 图片宽度 - 左右边距总和,可根据实际布局调整 let labelAvailableWidth = UIScreen.main.bounds.width - 70 - 44 // 示例:图片宽70,左右总边距44 // 3. 计算文本实际高度,font要和UILabel设置的字体保持一致 let textHeight = contentText.boundingRect( with: CGSize(width: labelAvailableWidth, height: .greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: [.font: UIFont.systemFont(ofSize: 15)], context: nil ).height // 4. 取两者最大值,上下边距按实际需求调整,示例上下边距总和为24 return max(textHeight + 24, 70 + 24) }
内容的提问来源于stack exchange,提问作者SwiftyS
相关产品推荐
相关产品推荐

