gpt4 book ai didi

ios - 由具有 UITableViewAutomaticDimension 的 FetchedResultsController 提供支持的 UITableView - 重新加载表格时单元格移动

转载 作者:可可西里 更新时间:2023-11-01 03:45:32 26 4
gpt4 key购买 nike

当前设置:

具有自动计算高度的 TableView:

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 152.0;
self.tableView.estimatedSectionHeaderHeight = 50.0;

每当 fetched results controller 更新它的数据时,tableview 就会重新加载:

 - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView reloadData];
}

该单元使用 Xib 配置。第一个标签被固定到单元格的顶部,每个后续标签被固定到它上面的标签的顶部,底部的标签被固定到单元格的底部。

问题:

每次我在 TableView 中的项目上设置“收藏夹”属性时,获取的结果 Controller 会被触发以重新加载表并更改滚动位置。我试图修复的正是滚动位置的这种变化。

附加信息

如果我使用固定的单元格高度,它可以解决问题,但我需要 UITableViewAutomaticDimension,因为第一个标签可以覆盖两行,其余标签可能存在也可能不存在。

示例

注意 - 当我选择 Fav 按钮时,它会在核心数据中设置 fav 属性并重新加载表格。为什么 table 会跳来跳去?

enter image description here

最佳答案

它的发生是由于以下顺序:

  1. UITableView 已初始化并显示 5 个单元格。 UITableView 知道每个单元格的高度。它通过调用方法 -tableView:heightForRowAtIndexPath: 在显示每个单元格之前询问其委托(delegate)人的确切高度。
  2. UITableView 从顶部精确滚动 3 个单元格。已知此单元格的高度恰好为 [60, 70, 90] = 220。 UITableView 的 contentOffset.y 现在是 220。
  3. UITableView 重新加载。它清除了所有关于细胞的知识。它现在仍然知道它的 contentOffset.y 是 220。
  4. UITableView 向其数据源询问一般指标 - 部分的数量和每个部分的行数。
  5. UITableView 现在开始填充其内容。首先,它需要知道其内容的大小以正确调整其滚动指示器的大小和位置。它还需要知道哪些对象 - 表头、部分标题、行、部分页脚和表页脚 - 它应该根据其当前 bounds 显示,哪个位置也由 contentOffset 。要开始放置可见对象,它首先需要跳过不可见垂直范围 [0…220] 内的对象。

    1. 如果您没有为任何 estimated... 属性提供值并且没有实现任何 tableViewController:estimated... 方法,那么 UITableView 会询问它的委托(delegate)关于确切的高度通过调用适当的委托(delegate)方法(例如 -tableView:heightForRowAtIndexPath:)来处理页眉、页脚和行。如果您的代表报告的对象数量和高度与重新加载前相同,那么您将看不到任何表格元素的位置和大小发生任何视觉变化。当你的表应该显示大量行时,这种“海峡”行为的缺点变得很明显,比方说 50000。UITableView 询问它的委托(delegate)关于这 50000 行中每一行的高度,你必须通过测量每个相应行的文本来自己计算它对象,或者当使用 UITableViewAutomaticDimension UITableView 做同样的测量本身,询问它的代表填充文本的单元格。相信我,它很慢。每次重新加载都会导致几秒钟的界面卡住。
    2. 如果您为 UITableView 提供了估计高度,那么它只会向其代理询问当前可见对象的高度。 [0…220] 垂直范围内的对象通过使用 estimatedRowHeight-tableView:estimatedHeightForRowAtIndexPath: 中为行提供的值以及节页眉和页脚的相应方法进行计数。通过将 estimatedRowHeight 设置为 60,您告诉 UITableView 跳过三行 (60 * 3 = 180) 并将第 4 行放置在距顶部可见边缘偏移量为 -40 的位置。因此,视觉“跳跃”了 40 个像素。

此处“正确”的解决方案是不调用 reloadData。仅为更改的对象重新加载行,使用 -reloadRowsAtIndexPaths:withRowAnimation:。在 NSFetchedResultsController + UITableView 的情况下使用这个 classic scheme .

关于ios - 由具有 UITableViewAutomaticDimension 的 FetchedResultsController 提供支持的 UITableView - 重新加载表格时单元格移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30107130/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com