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

标签 ios objective-c uitableview autolayout

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

这是我的 updateConstraints 实现:

- (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)]];
}

在 TableView Controller 中,我将行高设置为 UITableViewAutomaticDimension(我还设置了估计的行高)。在运行时,我遇到了一系列自动布局错误,所有表格 View 单元格几乎完全重叠。

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

  • V:|-(10)-[_nameLabel]
  • V:[_nameLabel(20)]
  • V:[_nameLabel]-(10)-[_tweetLabel]
  • V:[_tweetLabel]-(10)-|
  • V:[cell(44)]

我怀疑最后一个约束“UIView-Encapsulated-Layout-Height”强制高度为 44,是问题的原因,但我不太确定它从何而来,所以希望有人可以摆脱对这个问题的一些了解。

最佳答案

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

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

    请确保您已经在两个维度上定义了一个轴向约束链,即从 View 的一个边缘到另一个边缘的约束。也许确保这些约束正确的最简单方法是将您的自定义内容实现为普通的旧 UIView(易于测试),然后使用约束以便 UITableViewCell.contentView 拥护这种观点。 (我使用 this gist 自动构建“ View 环绕单元”。)

  2. 设置tableView.rowHeight = UITableViewAutomaticDimension

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

我花了很多时间来使用这个功能。 This github repo显示了七个自动调整表格 View 单元格的完整示例,其中包含一个包装文本标签——程序化的、基于 nib 的、基于 Storyboard的等等。

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

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

关于ios - 在 iOS 8 中自动调整 UITableViewCell 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25087969/

相关文章:

ios - 如何限制在uitableview中选择的行数

ios - 从 UITableView(不是 UITableViewController)转到 UIViewController

iphone - UITableViewController不会显示创建时的单元格

objective-c - 把很长的 NSString 剪掉一部分

ios - 没有重复使用的表格单元格的索引路径

objective-c - PresentModalViewController 稍后才会触发

iOS 14 - UIImagePickerController 中不显示缩略图

iphone - 核心数据是否保存来自不同线程的更改?

objective-c - 由于未找到 "nonatomic",使用 OpenCV 的 iPhone 5.1 应用程序崩溃

iphone - UITableView 滚动时重复单元格