只有在显示之后,setNeedsLayout才会重新传递单元格

我有一个单元格的表视图,有时有一个可选的UI元素,有时它必须被删除。 根据元素,标签被resize。

当单元格被初始化时,它会比稍后更窄。 当我将数据设置到标签中时,将从cellForRowAtIndexPath:调用此代码cellForRowAtIndexPath:

 if (someFlag) { // This causes layout to be invalidated [flagIcon removeFromSuperview]; [cell setNeedsLayout]; } 

之后,单元格返回到表格视图,并显示。 但是,该点的文字标签已经调整了其宽度,而不是高度。 一秒钟左右高度就会被调整,当所有的细胞已经被显示时,这个混蛋清晰可见。

重要提示,这只是在最初几个单元格的初始创build期间。 一旦它们被重用,一切都很好,因为可选视图被删除,并且标签已经正确地形成了以前的用法。

为什么在setNeedsLayout之后但在显示之前没有完全重新布局单元格? 显示之前不应该UIKit检查无效的布局?

如果我做

 if (someFlag) { [flagIcon removeFromSuperview]; [cell layoutIfNeeded]; } 

所有得到调整一次,但它似乎是一个不正确的方式来编写代码,我觉得我失去了别的东西。


有关如何创build单元格的更多代码:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ProfileCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; [cell setData:model.items[indexPath.row] forMyself:YES]; return cell; } // And in ProfileCell: - (void)setData:(Entity *)data forMyself:(BOOL)forMe { self.entity = data; [self.problematicLabel setText:data.attributedBody]; // Set data in other subviews as well if (forMe) { // This causes layouts to be invalidated, and problematicLabel should resize [self.reportButton removeFromSuperview]; [self layoutIfNeeded]; } } 

另外,如果重要,故事板单元格看起来像这样,一旦标志图标被移除,可选约束就会被接pipe: 故事板中的约束

我同意调用layoutIfNeeded似乎是错误的,即使它适用于你的情况。 但是我怀疑你错过了什么。 虽然我还没有对这种方式进行过任何研究,但是根据我的经验,在使用自动布局的表格中,经过dynamic布局的单元格有点儿麻烦。 也就是说,在运行时删除或添加子视图到单元格时,会看到生涩的布局。

如果您正在寻找替代策略(使用自动布局),则可以UITableViewCell并覆盖layoutSubviews 。 自定义表格单元格可以在公共API中公开可以在tableView:cellForRowAtIndexPath:的实现中设置的标志。 单元格的layoutSubviews方法将使用该标志来确定是否应该包含可选的UI元素。 但是我不能保证这会消除这个问题。

第二个策略是devise两个单独的单元格types,并在tableView:cellForRowAtIndexPath:根据需要在两者之间进行交换。

你已经添加了额外的代码,所以我有另一个build议。 在单元格的setData:forMyself:方法中,尝试调用setNeedsUpdateConstraints而不是layoutIfNeeded