dequeued UITableViewCell具有不正确的布局,直到滚动(使用autolayout)

时间:2013-02-21 06:01:01

标签: iphone ios objective-c interface-builder

我有一个自定义UITableViewCell子类,它在Interface Builder中应用了autolayout约束。该单元格包含多个视图,包括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后面。但是,当我将屏幕上的单元格滚动,暂停,然后向后滚动时,文本会被正确截断。

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

我已尝试为[cell setNeedsLayout]中的单元格调用[cell setNeedsDisplay]cellForRowAtIndexPath,并在延迟后执行它们。两者都没有效果。

滚动屏幕是什么导致细胞正确显示,我该如何复制或解决潜在问题?

编辑:

调用

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

为了重新加载单元格,似乎会导致布局第一次正确显示。

但是,它现在打破(偶尔)滚动(即,当向上滚动时,布局约束现在没有正确应用)。

[cell setNeedsLayout]中呼叫cellForRowAtIndexPath似乎无法解决此问题。

EDIT2:

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

这反映了第一次编辑时出现的问题 - 这是问题的第二次渲染(让我觉得它可能与重用单元格有关吗?)

2 个答案:

答案 0 :(得分:38)

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

即使在IB中使用自定义样式设计的单元格也是如此,该样式没有可见的textLabeldetailTextLabel属性。

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

答案 1 :(得分:8)

根据这个multiple lines UILabel GitHub issue,这是一个挥之不去的iOS错误。

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

以下解决方法仅部分有效:它需要重新绘制UITableView两次,但仍未涵盖所有方案。

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.setNeedsLayout()
    tableView.layoutIfNeeded()
    tableView.reloadData()
}

备注:

  • 使用UITextView是多行UILabel的绝佳替代品,没有错误。 UITextView也没有出现任何IULabel其他奇怪的内容,例如alignment errorsflickering
  • SO-25947146还有一个替代解决方案,这对我不起作用,但值得一提。
  • self.tableView.editingtrue
  • 时,似乎会突出显示
  • 使用tableView.estimatedRowHeight的低值可以减少出现次数
  • SwiftArchitect/TableViewControllerRowHeightBug gist
  • 上的错误演示