UITableViewCell + 动态高度 + 自动布局

4
我来自这个很棒的答案:
在UITableView中使用自动布局实现动态单元格布局和可变行高

我已经实现了那个答案中描述的内容,但是我面临着一个略微不同的情况。我没有一个UILabel,而是有一个动态列表的UILabel
我创建了一张图片,展示了一些表格视图应该呈现的不同情况: enter image description here 在当前仓库状态下,单元格无法垂直增长以适应单元格的contentView
更新 REPO: https://github.com/socksz/DynamicHeightCellAutoLayout 如果您尝试从仓库获取项目并运行它,您可以看到我所指的问题。我无法弄清楚缺少什么才能让它正常工作。

你现在提出的问题是关于要添加哪些约束条件。为了弄清楚这一点,您需要描述布局工作的“规则”。您能否再解释一下“标签如果其内容过长则需要缩小”的意思?这是否意味着您希望字体大小缩小,或者每个标签只允许1行文本,还是其他什么?更重要的是,由于您正在处理表格视图单元格和行高度,无论有多少标签,您是否始终希望单元格垂直增长以适合每个标签? - smileyborg
@smileyborg:是的,我希望单元格可以垂直增长以适应每个标签,无论有多少个。收缩的东西有效,因为每个标签都将adjustsFontSizeToFitWidth属性设置为YES。如果您运行了该项目,则会发现该单元格不会垂直增长以适应contentView,遗憾的是。 - Fred Collins
2个回答

3
问题出在您使用的第三方组件FXLabel上,而不是与表格视图或其中的自动布局相关的任何代码。为了支持自动布局,UIView的自定义子类必须适当地实现-[intrinsicContentSize]方法,然后在更改时调用-[invalidateIntrinsicContentSize]。
在这种情况下,FXLabel似乎依赖于其超类实现(UILabel)上述方法,由于UILabel没有设计成以FXLabel实现的可变行距的方式处理,因此它不知道返回正确的intrinsicContentSize,因此自动布局计算是错误的(在这种情况下,由于内在内容大小太小)。请查看this excellent obcj.io article的“启用自定义视图进行自动布局”部分获取更多详细信息。
现在好消息是,从iOS 6开始,您应该能够使用标准UILabel中的属性字符串来完成此操作。请查看Stack Overflow answer here
如果您真的喜欢FXLabel,可以在GitHub项目上开启一个问题(或尝试自行修复并提交拉取请求)。

顺便说一下,您可以进行简单的测试来验证问题是否出现在FXLabel组件上,方法是将其设置为默认行间距,检查intrinsicContentSize属性的值,然后增加行间距并重新检查intrinsicContentSize属性的值。我敢打赌它仍然是相同的。 - smileyborg
我不再使用FXLabel,因为我不再需要行间距。很抱歉我没有告诉你。我正在更新问题,并提供更多细节和代码。 - Fred Collins
我已经更新了问题,并提供了一个简单的存储库来展示问题! :D - Fred Collins

1

若要自动设置行高和估算行高,请按照以下步骤使单元格/行高度布局的自动尺寸生效。

  • 分配并实现数据源和委托
  • UITableViewAutomaticDimension分配给rowHeight和estimatedRowHeight
  • 实现委托/数据源方法(例如heightForRowAt),并向其返回值UITableViewAutomaticDimension

-

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

在UITableviewCell中使用标签示例

  • 将行数设置为0(和换行模式为truncate tail)
  • 相对于其父视图/单元格容器设置所有约束(顶部、底部、右侧和左侧)。
  • 可选: 如果想要标签覆盖的垂直区域最小化,即使没有数据,可以设置标签的最小高度。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接