【问题标题】:UITableViewCell with left and right labels. How to make them display correctly?带有左右标签的 UITableViewCell。如何让它们正确显示?
【发布时间】:2019-01-01 20:48:18
【问题描述】:

我有一个带有 2 个标签的 UITableViewCell,它们可以有不同的内容。有时左边的标签很大,右边的标签很小,或者是空的,有时右边的标签包含很多信息。

是否有可能仅通过使用约束和内容拥抱/抗压缩优先级来使它们正确显示(即不应截断任何标签并且标签的高度应尽可能小)?

我已经尝试为最小宽度添加约束,或者将压缩和拥抱的优先级更改为 1000,但我总是遇到一些问题,例如文本被截断(参见屏幕截图)或其中一个标签显示在 10 行和另一个仅在一行上(请参见第二个屏幕截图)。

这是我正在使用的一些示例数据(此处提供演示项目https://github.com/adi2004/iosamples/tree/master/TableView):

    let data = [
    (left: "left one two three four five", right: "7"),
    (left: "left one two three four five 6 7 more here", right: "right one two three four five 6 7"),
    (left: "left one two three four five 6 7", right: "right one two three four five 6 7 something"),
    (left: "6 = ", right: "right one two three four five 6 7"),
    (left: "left one two three four five 6 7 right one two three four five 6 7 eight right one two three four five 6 7 eight", right: "")
]

以下是我所面临问题的一​​些示例:

-- 或--

【问题讨论】:

  • 您好,您可以使用 Content Hugging Priority 实现此目的!请查看我的视频,它已解决您的 Tableview UILabel 问题希望对您有所帮助youtube.com/watch?v=g7Hlf7U0A9w
  • 谢谢,Yogesh。但是,当您事先不知道哪个标签应该更大时,这仍然不能解决问题,或者您会遇到其中一个标签被压扁并且会占用太多垂直空间的情况。
  • 您是否尝试过使用UIStackView
  • 如果您不知道哪个标签,请检查一次,但使用此优先级您可以做到这一点,请告诉我您现在卡在哪种情况下

标签: ios swift


【解决方案1】:

首先检查这个屏幕截图。满足你的要求了吗?

从您的 cmets 其他问题来看,我可以说,这就是您要找的。​​p>

这些是我为此创建单元格所采取的步骤:

  1. 在您的表格视图中添加TableViewCell,为其提供标识符和单元格类。
  2. 在此单元格中添加UIStackview Alignment = Fill, Distribution = Fill Proportionally, Spacing = 0。给 stackview 提供顶部、底部、前导、尾随约束,目前我使用 value = 12。(使用任何你想要的边距)
  3. 在这个 stackview 中添加 2 个 UIView,为这两个视图添加背景,现在,我给每个视图添加了绿色和红色。
  4. 现在将 UILabel 添加到每个 UIView,设置 numberOfLines = 0,为每个标签赋予值为 0 的顶部、底部、前导和尾部约束。现在,只需将 IBOutlets 连接到相应的单元类。

您需要的单元格已准备好,在数据源中设置您想要的值并运行代码。让我知道您需要的任何进一步帮助。确保在 UIView 中添加 UILabel,而不是直接添加到 UIStackview。这样做是因为,stackview 中的多行标签永远不会给你正确的结果。

更新:

正如@Gal 指出的那样,上面的代码在 dequing 时不起作用。这是我为解决相同问题所做的更改。

更改 1: 更新 cellForRowAtIndexPath 以使 containerViews 的 intrinsicContentSize 无效,并要求单元格再次布局约束。这是我的实现:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "TestCell") as! TestCell;
    cell.leftLabel.text = data[indexPath.row].left;
    cell.rightLabel.text = data[indexPath.row].right;
    cell.leftLabel.superview!.invalidateIntrinsicContentSize();
    cell.rightLabel.superview!.invalidateIntrinsicContentSize();
    cell.layoutIfNeeded()
    return cell;
}

更改 2: 进行上述单一更改适用于所有情况,除了任何标签的文本值为空的情况(在该 uiview 显然已从 stackview 中删除,由 stackview 本身)。所以,为了防止这种情况,我再次更新了我上面的cellForRowAtIndexPath 代码,确保任何标签的文本都没有变空。如果为空,则在此处仅添加空白空间。会是这样,

let leftText = data[indexPath.row].left;
if leftText.isEmpty{
    cell.leftLabel.text = " "
}else{
    cell.leftLabel.text = leftText;
}

let rightText = data[indexPath.row].right;
if rightText.isEmpty{
    cell.rightLabel.text = " "
}else{
    cell.rightLabel.text = rightText
} 

进行上述更改后。截图会有非常小的切片,如果你隐藏了背景,那你就找不到了,它存在那里。这是截图:

【讨论】:

  • 感谢梅胡尔的回答!在您的屏幕截图中看起来很棒。我也在我的示例项目中尝试过它,它可以工作,但是......当我滚动表格时可悲或神秘地,出队的单元格没有正确显示。见这里:imgur.com/a/L0LuDnx
  • 好像越来越好了。我认为,最后,需要一些代码才能使其正常工作。我尝试了您的更改以及我发布的数据源示例,它工作正常!但是如果我只添加这 2 个新值:(left: "left label only, the other one is empty string", right: " "), (left: " ", right: "right label only, the other one is empty string"),我会看到一些单元格仍然没有正确出列:youtube.com/watch?v=pvGFRjFuOkU
  • @Adi :我认为您尚未应用我更新的代码更改,我已按照您的建议添加以上行进行检查。它工作 100% 正常。
  • @Adi 这里是代码:wetransfer.com/downloads/…
  • @Adi : 如果您无法从代码中获取任何信息,请告诉我。
【解决方案2】:

主要思想是声明标签的宽度。为此,您必须声明一些规则。

首先决定哪个标签的优先级更高,假设您需要左标签的优先级更高,因此将其Horizo​​ntal Content Hugging Priority设置为大于右标签

现在为两个标签设置它们的最小宽度。这可以通过设置具有特定常数和关系大于或等于

的宽度约束来实现


如果您需要在标签之间始终保持相同的“间距”,请将它们的共同约束设置为关系 Equal

【讨论】:

  • 感谢罗伯特的提示。我认为这可能接近我所需要的,但即使我添加了宽度约束,有时单元格在出列时也无法正确显示。见这里:imgur.com/a/1Ncg1pc。我还在 GitHub 上添加了一个演示项目:github.com/adi2004/iosamples/tree/master/TableView
  • @Adi 你想要单元格之间的间距相同吗?用关系 Equal 设置它们的共同约束。
  • @Adi 第二个问题(没有文本的标签)是由于宽度限制的原因,标签的最小宽度总是等于宽度限制。如果你想避免它,你可以在没有任何文字的地方隐藏标签。
  • 间距并不重要。我只对使用体面的 UI 显示标签的内容感兴趣。第二个标签也可以有一些非常小的东西,比如1
  • @Adi 看,在这种情况下,您必须规定这些标签的宽度。 Xcode/Swift 不会为你做这些
【解决方案3】:

UIStackView 的另一种方法,

注意事项:

  • UITableView应该有,

    tableView.estimatedRowHeight = 44.0
    tableView.rowHeight = UITableView.automaticDimension
    
  • 保留Label 1Label 2numberOfLines = 0

  • UIStackView 应该有Fill Proportionally 分布

【讨论】:

  • 我也试过UIStackView,但如果我使用Fill Proportionally,标签2为空,标签1不会使用所有水平空间。
  • 顺便说一句,使用 UIStackViewFill Proportionally 仅适用于 numberOfLines = 1
猜你喜欢
  • 2016-06-11
  • 1970-01-01
  • 2015-01-01
  • 2018-03-05
  • 2020-01-31
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
相关资源
最近更新 更多