出队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
子类textLabel
或defaultTextLabel
上命名属性,则IB将忽略您指定的约束,并使用默认约束覆盖它们,而不会发出警告。
甚至在使用自定义样式devise的单元格上也是如此,它们没有可见的textLabel
或detailTextLabel
属性。
如果在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.editing
为true
时显着发生 - 对
tableView.estimatedRowHeight
使用较低的值可以减less事件的发生 - 演示SwiftArchitect / TableViewControllerRowHeightBug的bug