在 iOS 8 中自动调整 UITableViewCell 的大小

Auto-sizing UITableViewCell in iOS 8(在 iOS 8 中自动调整 UITableViewCell 的大小)

本文介绍了在 iOS 8 中自动调整 UITableViewCell 的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多行标签的 UITableViewCell 子类,我希望单元格根据该标签的内容动态调整自身大小.我知道 iOS 8 引入了基于 AutoLayout 约束的自动调整单元格大小,并且我已经在 SO 上找到了几个这样的示例,但是我仍然无法正确实现此行为.

I have a UITableViewCell subclass which contains a multiline label, and I would like the cell to size itself dynamically based on the content of that label. I'm aware that iOS 8 introduced auto-sizing cells based on AutoLayout constraints, and I've found several examples of this already on SO, but I'm still having some trouble implementing this behavior properly.

这是我的 updateConstraints 实现:

Here's my updateConstraints implementation:

- (void)updateConstraints {
    [super updateConstraints];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_nameLabel(==20)]-10-[_tweetLabel]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_nameLabel, _tweetLabel)]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_avatarView]-10-[_nameLabel]-10-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_avatarView, _nameLabel)]];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_nameLabel]-10-[_tweetLabel]-10-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_nameLabel, _tweetLabel)]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[_avatarView]-10-[_tweetLabel]-10-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_avatarView, _tweetLabel)]];

    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[_avatarView(==45)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_avatarView)]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[_avatarView(==45)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_avatarView)]];
}

在表格视图控制器中,我将行高设置为 UITableViewAutomaticDimension(我还设置了估计的行高).在运行时,我收到一系列自动布局错误,并且所有表格视图单元格看起来几乎完全重叠.

In the table view controller I set the row height to UITableViewAutomaticDimension (and I set an estimated row height as well). At runtime, I get a series of auto layout errors and all of the table view cells appear nearly completely overlapped.

自动布局冲突发生在以下约束之间:

The auto layout conflicts are between the following constraints:

  • V:|-(10)-[_nameLabel]
  • V:[_nameLabel(20)]
  • V:[_nameLabel]-(10)-[_tweetLabel]
  • V:[_tweetLabel]-(10)-|
  • V:[单元格(44)]

我怀疑最后一个约束UIView-Encapsulated-Layout-Height",它强制高度为 44,是问题的原因,但我不太确定它来自哪里,所以希望有人可以摆脱对这个问题有所了解.

I suspect the last constraint, "UIView-Encapsulated-Layout-Height", which forces a height of 44, is the cause of the issue, but I'm not quite sure where that comes from, so hopefully somebody can shed some light on the issue.

推荐答案

为了实现表格视图单元格的自动行高,您需要执行以下操作:

In order to implement automatic row heights for table view cells, you need to do the following:

  1. 在单元格的 contentView 中实现自动布局约束,允许视图表达其首选高度.请务必将 UILabel 设置为多行自动换行.

  1. Implement Auto Layout constraints within the cell's contentView that allow the view to express its preferred height. Be sure to set UILabels to word wrap over multiple lines.

确保您已在两个维度上定义了一个轴向约束链,即从视图的一个边缘一直到另一边的约束共同绑定.确保这些约束正确的最简单方法可能是将自定义内容实现为普通的旧 UIView(易于测试),然后使用约束使 UITableViewCell.contentView 拥抱那个观点.(我使用 this gist 来自动构建视图包装单元".)

Be sure you've defined an axial chain of constraints in both dimensions, that is, constraints that collectively bind all the way from one edge of the view to the other. Perhaps the easiest way to be sure these constraints are correct is to implement your custom content as a plain old UIView (which is easy to test), and then use constraints so that the UITableViewCell.contentView hugs that view. (I use this gist to automate building the "view-wrapping cell".)

设置 tableView.rowHeight = UITableViewAutomaticDimension

设置 tableView.estimatedRowHeight = 400 或其他一些相当大的值,以便在估计值过低时解决一些 UIKit 错误.

Set tableView.estimatedRowHeight = 400 or some other reasonably generous value, in order to workaround some UIKit bugs when the estimate is too low.

我花了很多时间来使用这个功能.此 github 存储库 展示了七个完整的自调整表格视图单元格示例,其中包含换行文本的单个标签——程序化、基于 nib、基于故事板等.

I have spent a puzzling amount of time working with this feature. This github repo shows seven complete examples of self-sizing table view cells containing a single label of wrapping text -- programmatic, nib-based, storyboard-based, etc..

最后,如果您看到有关UIView-Encapsulated-Layout-Height"的不可满足约束的警告,请不要太担心.或在第一次加载表格视图时类似.这是 UITableView 创建单元格的初始过程的产物,根据自动布局约束确定其大小应该,并保留 UITableViewCell 紧紧包裹着它的 contentView.我上面提到的 repo 有更广泛的讨论和代码,用于探索 API 的这个有点尴尬的角落.

Finally, do not worry too much if you see warnings about unsatisfiable constraints mentioning "UIView-Encapsulated-Layout-Height" or similar at the first time the table view loads. This is an artefact of UITableView's initial process for creating a cell, determining what its size should be based on Auto Layout Constraints, and keeping the UITableViewCell tightly wrapping its contentView. The repo I mentioned above has more extensive discussion and code for exploring this somewhat awkward corner of the API.

您应该只担心违反约束的警告,即使它们在单元格加载并滚动了一点之后仍然存在,或者如果您最初看到不正确的布局.在这种情况下,第一步应该始终是确保您的约束是正确的,如果可能的话,在纯 UIView 中单独开发和测试它们.

You should only worry about constraint-violation warnings if they persist even after the cell has loaded and has scrolled a bit, or if you are seeing incorrect layouts initially. In this case, again, the first step should always be to ensure your constraints are correct by developing them and testing them in isolation if possible, in a plain UIView.

这篇关于在 iOS 8 中自动调整 UITableViewCell 的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:在 iOS 8 中自动调整 UITableViewCell 的大小

基础教程推荐