ios - setNeedsLayout 仅在显示后重新布局单元格

标签 ios uitableview autolayout

我有一个带有单元格的 TableView ,有时它有一个可选的 UI 元素,有时它必须被删除。 根据元素,标签会调整大小。

初始化单元格时,它比以后要窄。当我将数据设置到标签中时,从 cellForRowAtIndexPath:

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

之后,单元格返回到表格 View ,并显示出来。但是,此时的文本标签已调整其宽度,但未调整高度。高度在一秒钟左右后得到调整,当所有单元格都已显示时,抖动清晰可见。

重要说明,这仅在最初创建前几个单元格时出现。一旦它们被重用,一切都很好,因为可选 View 被删除并且标签已经根据以前的用法正确调整大小。

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

如果我这样做

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

一下子就全部调整好了,但是写代码的方式似乎不对,我觉得我还漏掉了其他东西。


关于如何创建单元格的更多代码:

- (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];
    }
}

此外,如果重要的话,在 Storyboard单元格中看起来像这样,一旦移除标志图标,可选约束就会接管: Constraints in the storyboard

最佳答案

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

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

第二个策略是设计两个单独的单元格类型,并根据需要在 tableView:cellForRowAtIndexPath: 中交换这两个单元格类型。

关于ios - setNeedsLayout 仅在显示后重新布局单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20925247/

相关文章:

ios - 如何以编程方式添加导航栏到presentModalViewController?

ios - Xcode 界面生成器 : Make a view's center X equal to third of its superview

ios - 简单自定义 UITableViewCell 的自动布局错误

ios - 想要在后台模式下运行广告外围设备iOS Swift

ios - 在 iOS8 中使用 Swift 点击时如何隐藏/显示 tabBar

iphone - 在手机而不是模拟器上测试时,由于 UITableView 滚动位置居中导致应用程序崩溃

objective-c - UITableViewCell 子类未初始化

ios - 将 UINavigationController 添加到 UIView?

ios - 如何在没有 Storyboard的情况下启动另一个 View Controller ?

ios - 以编程方式使用布局 anchor 的自动布局不起作用