带有约束更新的 UITableViewCell 导致 UITableView 跳来跳去

Posted

技术标签:

【中文标题】带有约束更新的 UITableViewCell 导致 UITableView 跳来跳去【英文标题】:UITableViewCell with Constraint updates cause UITableView to jump around 【发布时间】:2015-04-03 14:35:14 【问题描述】:

总结

在 tableView 中调整和重新加载行,其中每个单元格都有一个由约束计算的动态高度,这会导致许多其他单元格不必要地重新计算。我该如何解决这个问题?

可以在here找到一个示例项目。

加长版

我有一个显示公司详细信息的视图和具有更详细信息的可变数量的单元格(或卡片)。我在 UITableViewController 中使用自动布局约束(主要由 this Ray Wenderlich tutorial 提供帮助)实现了这一点,它具有动态大小的单元格。

视图具有以下高度可变的单元格:

第 0 节 第 0 行:标题图片 第 1 行:公司信息 第 2 行:按钮 第 X 节 > 0 第 0 行:关于卡片

“关于卡片”可能有也可能没有标题图片,并且可以展开以显示整个文本。

目前我有四个问题:

    UITableViewController 使用animating: true 推送。但是,tableView 从导航栏后面开始,并在完成动画后跳下。不知道为什么。

更新这似乎并没有持续发生。喜悦。

    当执行应重新加载按钮以指示状态更改的操作时,它会很好地重新加载按钮单元。但是,它也会导致公司信息单元向下跳并向上移动。

使用以下代码更新单元格:

func organizationRequestsUpdated() 
    self.tableView.reloadSections(NSIndexSet(index: 0), withRowAnimation: UITableViewRowAnimation.None)

    点击关于卡片应该会展开它。我目前通过在单元格初始设置label.numberOfLines = 5 并使用它来切换扩展卡来实现这一点:

    @IBAction func tapped(sender: UITapGestureRecognizer)
    
        if let view = sender.view?.superview as? OrganizationDetailAboutCardCell 
            tableView.beginUpdates()
            view.toggleReadMore()
            tableView.endUpdates()
        
    
    func toggleReadMore() 
        let expanded = aboutTextLabel.numberOfLines == 5
        aboutTextLabel.numberOfLines = expanded ? 5 : 0
    
    

我很确定所有这些问题都与带有约束的单元格自动调整大小有关。但是,我目前不知道如何解决它。有没有人用约束自动调整单元格大小并更新单元格高度,而所有 tableView 都没有做奇怪的跳跃?

    返回 UITableViewController 时,大多数单元格的高度都错误。不知道为什么。

我尝试过的事情

问题 2

对于第 2 个问题,我已经尝试更新重新加载按钮单元格;

self.tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: 2, inSection: 0)], withRowAnimation: UITableViewRowAnimation.None)

但是,这违反直觉导致该部分中的所有单元格重新计算不正确,最终导致一堆太小的单元格。我也试过这个UITableViewRowAnimation.Fade,但是结果是一样的。

【问题讨论】:

当您使用UITableViewAutomaticDimension 时,似乎存在一个错误。请参阅this answer 和该问题的其他答案。 【参考方案1】:

您是否指定了估计的行高?当我这样做时,我发现这是我的许多布局问题的根源。

另一个可能的问题是您需要为标签分配字体以使其布局正确。因此,在您的 cellForRowAtIndexPath 方法中,指定应该在所有标签/文本字段/文本视图上使用的字体。

这里是一个示例项目:https://github.com/sgoodwin/SelfSizingCells。

祝你好运!

【讨论】:

谢谢!像魅力一样工作。顺便说一句,您的意思是重新指定标签字体,即使它们可能已经在 Interface Builder 中设置? 是的,部分原因是演示应用使用了系统的动态字体大小,因此需要重新分配。 UIFont 实例是不可变的,因此当动态字体首选项发生更改时,您需要重新分配字体以显示此更改。 这可能是第一个 UILabel 在开头截断的答案,即使它适当地调整了大小。

以上是关于带有约束更新的 UITableViewCell 导致 UITableView 跳来跳去的主要内容,如果未能解决你的问题,请参考以下文章

带有标题的自定义 UITableViewCell - 约束

从 cellForRowAt 更新时,UITableViewCell 中的活动约束不会更新

如何更新 UITableViewCell 约束常量并更新单元格高度

UITableViewCell 约束更新仅在滚动后发生

何时何地根据实际宽度更新 UITableViewCell 子视图的约束

如何在UITableViewCell内部更新UITableView的高度约束