【问题标题】:Automatically grow static table view cell height to fit label content height自动增加静态表格视图单元格高度以适应标签内容高度
【发布时间】:2017-10-18 17:40:42
【问题描述】:

这是我的单元格布局的低质量模型:

静态单元格(在情节提要中设置)的初始高度为 80。在此单元格内有两个视图。底部视图的固定高度为 40。顶部视图具有布局约束,以与上边距对齐并与底部视图垂直对齐。

顶视图内部是一个标签(蓝色)和一个按钮(黄色)

标签还具有与视图顶部对齐和与视图底部对齐的约束。该布局和约束背后的想法是,如果我将单元格的高度增加到 100,例如,底部视图高度保持 40,而顶部视图和标签高度将扩展到 60 高度。

我的标签有换行和行数设置为 0。我现在想要的是自动调整单元格的大小,以便在多行时显示标签的完整内容。我该怎么做?

我试过了:

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 80.0;

这不起作用。单元格高度始终保持为 80,与 UILabel 中的行数无关。

我也试过了:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension;
}

结果与我的第一种方法相同。

我尝试的更复杂的方法如下:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let heightLabel = self.heightForView(text: self.lblTitle.text!, font: UIFont(name: "Helvetica Neue", size: 18)!, width: self.lblTime.width);
    let heightView = (heightLabel + (80.0 / 2));

    print("title label height \(heightLabel)");
    print("title view height \(heightView)");

    if (heightView > 80.0) {
        return heightView;
    }

    return 80.0;
}

func heightForView(text: String, font: UIFont, width: CGFloat) -> CGFloat {
    let label: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude));
    label.numberOfLines = 0;
    label.lineBreakMode = .byWordWrapping;
    label.font = font;
    label.text = text;
    label.sizeToFit();

    return label.frame.height;
}

输出:

title label height 42.5
title view height 82.5

但这似乎也不起作用,因为其他行没有显示,只有标签的第一行。

我怎样才能让它工作?

编辑

我想当我知道标签的宽度时,计算标签高度的方法会起作用。但是我怎么知道呢?

【问题讨论】:

  • 而不是self.tableView.estimatedRowHeight = 80.0;estimatedRowHeight 设置为120.0;。 estimatedRowHeight将不允许tableView行超过80,如果你设置80。如果你需要它扩展超过80,你必须设置它为120。更多developer.apple.com/reference/uikit/uitableview/…
  • 如果它应该大于 120?高度可以是动态的每个高度(取决于标签的行数)。
  • 我刚刚给了你一个大概的高度。您必须根据您显示的消息设置最大值。
  • 所以这是一种绝对行不通的方法,因为我有多个标签,它们都可以有不同的高度。
  • 我觉得你很困惑。您不需要计算每行的高度。如果你设置estimatedRowHeight。关注此raywenderlich.com/129059/self-sizing-table-view-cells

标签: swift uitableview


【解决方案1】:

根据个人经验,让 UITableCells 正确增长是 iOS 中最烦人的事情之一。最大的问题通常是约束。如果它们不完美,细胞就不会生长。

关键是要能够从单元格内容视图的顶部到内容视图的底部绘制一条直线。因此,从您的示例常量来看,应该如下所示。

topView.top == contentView.top
label.top == topView.top
label.bottom == topView.bottom
topView.bottom == bottomView.top
bottomView.height == 40
bottomView.bottom == contentView.bottom

如果没有这条直线,布局就无法确定标签显示所有内容的正确高度。

所以你在一个新的示例项目中寻找的一个相当简单的版本:

class ViewController: UITableViewController {
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.estimatedRowHeight = 80.0

        label.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
}

使用相同的布局: Layout of Table Cell

结果在模拟器中显示如下。 Result Image

【讨论】:

  • 谢谢。但我已经得到了正确的约束。如果我增加情节提要中的单元格高度,则布局行为会按预期正常工作。唯一的问题是获得单元格的正确高度。
  • 要尝试的另一件事是覆盖函数 heightForRowAtIndexPath。不知道为什么,但对于静态单元来说,这似乎是必要的。
  • 覆盖 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }
  • 刚刚更新的答案。来自工作样本的附加信息。稍后我会在 GitHub 上获取示例项目。
  • 嗨,这似乎有效,但它也会挤压我所有的其他细胞。是否可以提供最小高度?
猜你喜欢
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
相关资源
最近更新 更多