出队UITableViewCell有不正确的布局,直到滚动(使用自动布局)

我有一个自定义的UITableViewCell子类,它已经在Interface Builder中应用了自动布局约束。 单元格包含多个视图,包括UITextField

相关地, UITextField的大小受到限制,使得它和下一个视图之间有默认的水平间距。

这个单元格如下所示:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"ProgressCell"; ProgressCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath] cell.textField.text = @"Some string that is different for each cell"; return cell; } 

当单元格第一次出现时, UITextField超出了正确的框架,并出现在其右侧UIView后面。 但是,当我从屏幕上滚动单元格,暂停,然后向回滚动文本被正确截断。

下面显示了一个例子(在第二个编辑处)。

我已经尝试在cellForRowAtIndexPath中为[cell setNeedsDisplay] [cell setNeedsLayout][cell setNeedsDisplay] ,并在延迟后执行它们。 两者都不是有效的。

什么是滚动屏幕做这导致单元格显示正确,我怎么可以复制这个或修复的根本问题?

编辑:

调用

 [self.tableView reloadData]; [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic]; 

为了重新装入单元格,出现导致布局第一次正确显示。

但是,它现在在滚动时(偶尔) 会中断 (即滚动回滚时,布局约束现在不能正确应用)。

调用cellForRowAtIndexPath中的[cell setNeedsLayout]似乎不能解决这个问题。

EDIT2:

如此处所示,顶部单元格正确显示(如底部单元格一样),直到我向下滚动屏幕。 它消失了。

这反映了第一次编辑的问题 – 这是第二次渲染是这个问题(使我认为这可能与重用单元格有关)?

如果您在UITableViewCell子类textLabeldefaultTextLabel上命名属性,则IB将忽略您指定的约束,并使用默认约束覆盖它们,而不会发出警告。

甚至在使用自定义样式devise的单元格上也是如此,它们没有可见的textLabeldetailTextLabel属性。

如果在UITableViewCell子类中添加UIImageView属性的属性并将其命名为imageView也会发生这种情况。

根据这个多行UILabel GitHub的问题 ,这是一个挥之不去的iOS错误。

我发现在iOS 9+中,这种情况主要发生在编辑模式下,具有很多不可预测性。

以下解决方法仅部分工作:它需要重绘UITableView两次,仍然不包括所有情况。

 override func viewDidLoad() { super.viewDidLoad() tableView.setNeedsLayout() tableView.layoutIfNeeded() tableView.reloadData() } 

笔记:

  • 使用UITextView是一个很好的替代多行UILabel ,没有错误。 UITextView不会显示任何IULabel其他古怪,如alignment错误或闪烁 。
  • 在SO-25947146上也有一个替代解决scheme,这对我不起作用,但值得一提。
  • 似乎在self.tableView.editingtrue时显着发生
  • tableView.estimatedRowHeight使用较低的值可以减less事件的发生
  • 演示SwiftArchitect / TableViewControllerRowHeightBug的bug