如何基于多视图配置动态UITableViewCell的高度

Posted

技术标签:

【中文标题】如何基于多视图配置动态UITableViewCell的高度【英文标题】:How to Configure Height of Dynamic UITableViewCell Based on Multiple Views 【发布时间】:2017-04-11 21:55:08 【问题描述】:

我正在开发一个从服务器中提取数据并在UITableView 中显示数据的应用程序。数据是动态的,会提取来自社交网络的项目。

目前,我正在提取个人资料图片、用户名和社交网络句柄。该数据以UITableView 的形式显示,类似于 Tweetbot 显示其数据的方式。以下是 Tweetbot 时间线的参考:

如您所见,在最上面的帖子中,正文包含四行。在我的第二篇文章中,正文仅包含一行。您还可能注意到,在我的帖子中,单元格的高度没有缩小,导致单元格剪裁了UIImageView。从图像顶部到单元格顶部的空间似乎与从图像底部到单元格底部的空间相等。但是当正文中有多行文本时,单元格的高度会增加。

我通常设置UITableViewestimatedRowHeightrowHeight 属性以通过固定内容来允许动态高度,但我不知道如何配置自动布局以允许基于多个视图的动态单元格高度.

我配置此布局的一个想法是检测单元格的高度,正文文本固定在单元格的底部,从而创建动态高度。然后,如果单元格的高度大于图像的高度和从图像到单元格的顶部约束乘以 2(图像视图与单元格顶部和底部之间的底部和顶部间距)的总和,我将删除正文底部之间的约束,并将约束添加到图像和单元格的底部。

简而言之,如果一个单元格只包含一行文本,我如何确保该单元格符合图像的尺寸而不剪切图像?

【问题讨论】:

【参考方案1】:

我通过创建两个约束解决了这个问题;一个在图像底部和单元格底部之间,另一个在标签底部和单元格底部之间。

我将图像和单元格之间的约束设置为具有所需的constantrelation of greaterThanOrEqual,而标签和单元格之间的约束具有所需的constant 和@987654326 的relation @。通过这样做,如果正文变得更大,那么greaterThanOrEqual 将允许图像和单元格之间的约束增长,但绝不允许它变得小于所需的constant 并导致单元格剪切内容。

【讨论】:

【参考方案2】:

我正在回答这个问题,因为听起来您的约束设置不正确(来自您自己对这个 SO 问题的回答)。

如果您的限制得到满足,您将获得作为设置的一部分免费计算的动态高度。

这是我制作的一个简单示例,用于展示自我调整大小UITableViewCells:

https://github.com/runmad/SelfSizingUITableViewCellExample

这是一个单元格的示例约束:

class TableViewCell: UITableViewCell


    let topView = UIView()
    let label = UILabel()
    let bottomView = UIView()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) 
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        contentView.backgroundColor = UIColor.white

        contentView.addSubview(topView)
        topView.backgroundColor = UIColor.red
        topView.translatesAutoresizingMaskIntoConstraints = false
        topView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
        topView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
        topView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
        topView.heightAnchor.constraint(equalToConstant: 100).isActive = true

        contentView.addSubview(label)
        label.numberOfLines = 0
        label.backgroundColor = UIColor.lightGray
        label.translatesAutoresizingMaskIntoConstraints = false
        label.topAnchor.constraint(equalTo: topView.bottomAnchor, constant: 10).isActive = true
        label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
        label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true

        contentView.addSubview(bottomView)
        bottomView.backgroundColor = UIColor.blue
        bottomView.translatesAutoresizingMaskIntoConstraints = false
        bottomView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 10).isActive = true
        bottomView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
        bottomView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
        bottomView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
        bottomView.heightAnchor.constraint(equalToConstant: 20).isActive = true
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    static func reuseIdentifier() -> String
    
        return String(describing: self)
    


关键点(无论单元格中的子视图数量如何)是单元格中的子视图必须限制在单元格的所有边缘,这允许它根据@987654324 调整大小@任何观点。如果你有多个子视图,你必须确保子视图之间的约束是正确的。

【讨论】:

以上是关于如何基于多视图配置动态UITableViewCell的高度的主要内容,如果未能解决你的问题,请参考以下文章

如何让drupal视图显示基于节点的动态内容

如何向 UINavigationController 添加一个在任何子视图上方可见的视图

吴文君,郭枭:基于多路径传输的动态负载均衡路由算法

多数据源动态配置及事务控制

基于Spring+Mybatis的多数据源动态切换

如何使用动态视图 iOS Swift 处理导航?