【问题标题】:Auto-sizing UITableViewCell in iOS 8在 iOS 8 中自动调整 UITableViewCell 的大小
【发布时间】:2014-09-25 02:44:10
【问题描述】:

我有一个包含多行标签的 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)]];
}

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

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

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

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

【问题讨论】:

  • 您是否检查过您的 UITableViewCell 上的 translatesAutorezisingMaskIntoConstraints 是否设置为 NO?
  • @kljhanson 刚刚尝试过,感谢您的建议,但现在一个大的灰色矩形占据了大部分屏幕(Xcode 的视图检查显示它有数百个单元格分隔符)。我肯定在委托方法中给出了正确的单元格计数,知道为什么会发生这种情况吗?
  • 不确定这是否是 Apple 自动布局错误,但本文中的用户建议它是:stackoverflow.com/questions/25059443/… 我自己的动态 tableviewcell 高度也得到相同 (44) 的单元格高度约束冲突。它似乎只出现在 iOS 8 中,iOS 7 正在运行。奇怪的是,如果所有单元格的高度相同并且您没有进行动态单元格高度,则不会出现此问题。我真的希望这是一个 Apple 错误 >.

标签: ios objective-c uitableview autolayout


【解决方案1】:

您确定单元格上的 -translatesAutoresizingMaskIntoConstraints 设置为 NO 吗?如果不这样做,系统会根据 autoresizing mask 生成约束,这是以前在 iOS 上进行布局的方式,在使用 Auto Layout 时应该禁用。

【讨论】:

  • 感谢您指出这一点,我确实为单元格的子视图设置了该设置,但没有为单元格本身设置。
  • 但是当我将它设置在单元格上时发生了一件有趣的事情 - 一个灰色矩形现在占据了大部分屏幕,并且根据 Xcode 的视图检查,它有数百个表格视图分隔符,任何想法是什么原因造成的?我在委托回调中返回了正确的行数,所以不确定是什么原因。
  • 不知道这是否有帮助,但 Apple 的“updateConstraints”文档明确指出,“[super updateConstraints]”应该被称为实现的最后一步。
【解决方案2】:

我刚遇到这个问题。

从他们推荐的许多其他 Stackoverflow 帖子中:

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;

起初这对我不起作用。我发现我也需要这样做

self.frame = CGRectMake(0, 0, self.frame.size.width, 50);

我的自定义单元格的 init 方法看起来像他的:

-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if(self)
    {
        [self initViews];
        [self initConstraints];
    }

    return self;
}

我将代码放在我的“initViews”方法中:

-(void)initViews
{
    ...

    // fixes an iOS 8 issue with UIViewEncapsulated height 44 bug
    self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    self.frame = CGRectMake(0, 0, self.frame.size.width, 50);
}

问题消失了,我的单元格看起来也正确了。

这对你有用吗?

【讨论】:

  • 谢谢!就我而言,这些观点看起来不错,但不知何故我收到了很多警告。我按照你的建议添加了面具和框架。我想问题是默认高度 44 太小了,我的视图无法适应,即使高度在显示上拉伸,内部布局管理器还是会抱怨。我至少需要 200 个,所以我设置了一个安全框架 (0,0,w,200)。
【解决方案3】:

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

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

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

  2. 设置tableView.rowHeight = UITableViewAutomaticDimension

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

我花了很多时间来使用这个功能。 This github repo 展示了七个完整的自动调整大小的表格视图单元格示例,其中包含单个环绕文本标签——程序化、基于 nib、基于故事板等。

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

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

【讨论】:

  • 谢谢!我将tableView.estimatedRowHeight 更改为大值,一切正常:)
猜你喜欢
  • 2014-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多