当NSFetchedResultsController添加新记录时,如何阻止向上滚动UITableView?

一旦我向CoreData添加新评论,我的UITableView就会向上滚动。 NSFetchedResultsController知道它,将此注释放在表的底部,并将表滚动到顶部。 这是正常的吗?

我的例子:

就在我添加评论之前:

在此处输入图像描述

在我添加评论(不是预期的行为)之后:

在此处输入图像描述

它应该是这样的( 在我手动手动滑动之后 ):

在此处输入图像描述

这可能与以下情​​况有关:

  1. 这是我的NSFetchedResultsController排序描述符:

     NSSortDescriptor(key: "createdAt", ascending: false) //from the latest to the oldest 
  2. 但是我需要显示反向索引路径的注释( 最新版本位于最底层 )。 换句话说,当我需要使用indexPath我会使用:

     private func reversedIndexPathForIndexPath(indexPath: NSIndexPath) -> NSIndexPath { return NSIndexPath(forRow: fetchedResultsController.fetchedObjects!.count - indexPath.row - 1, inSection: 0) } 

NSFetchedResultsControllerDelegate

 //MARK: - NSFetchedResultsControllerDelegate func controllerWillChangeContent(controller: NSFetchedResultsController) { self.tableView.beginUpdates() } func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { switch type { case .Insert: if let newIndexPath = newIndexPath { tableView.insertRowsAtIndexPaths([reversedIndexPathForIndexPath(newIndexPath)], withRowAnimation: .Fade) } case .Delete: if let indexPath = indexPath { tableView.deleteRowsAtIndexPaths([reversedIndexPathForIndexPath(indexPath)], withRowAnimation: .Fade) } case .Update: if let indexPath = indexPath { tableView.reloadRowsAtIndexPaths([reversedIndexPathForIndexPath(indexPath)], withRowAnimation: .Fade) } case .Move: if let indexPath = indexPath, let newIndexPath = newIndexPath { tableView.deleteRowsAtIndexPaths([reversedIndexPathForIndexPath(indexPath)], withRowAnimation: .Fade) tableView.insertRowsAtIndexPaths([reversedIndexPathForIndexPath(newIndexPath)], withRowAnimation: .Fade) } } } func controllerDidChangeContent(controller: NSFetchedResultsController) { tableView.endUpdates() } 

它与我的问题有关吗?

编辑答案:

我能够通过以下步骤重现这个故障:

  1. UITableView ,其rowHeight设置为UITableViewAutomaticDimension ,非零estimatedRowHeight
  2. 表格滚动到最底部,最后一个单元格在底部边缘完全可见。
  3. 将新单元格插入到最后一个单元格下方会导致单元格向下移动几个点(在我的设置中它从5到40不等)。

此行为的来源需要进一步调查。

目前唯一的解决方案是不使用UITableViewAutomaticDimension并从tableView:heightForRowAtIndexPath:返回行高tableView:heightForRowAtIndexPath: .

顺便说一下,倒排索引路径的实现有一个重大缺陷。 当FRC调用它的委托方法controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: ,所有删除索引路径都属于更改前数据集,所有插入索引路径 – 后更改一个。 当你在controllerWillChangeContent:controllerDidChangeContent:fetchedResultsController.fetchedObjects将包含更改后的数据集,我想(虽然需要检查)。

我找到了适合我的东西。 我遇到了同样的问题,我的estimatedRowHeight是33,我的所有细胞都大于33。

我刚刚将estimatedRowHeight更改为最大单元格高度(或大于最大单元格高度)

  self.table.estimatedRowHeight = 310 self.table.rowHeight = UITableViewAutomaticDimension 

像魅力一样工作,所有单元格现在都是自动调整的,当核心数据执行更新/删除/插入时,uitableview不会滚动到顶部或底部