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

Bar*_*zyk 4 uitableview nsfetchedresultscontroller ios swift

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

我的例子:

就在我添加评论之前:

在此输入图像描述

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

在此输入图像描述

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

在此输入图像描述

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

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

    NSSortDescriptor(key: "createdAt", ascending: false) //from the latest to the oldest
    
    Run Code Online (Sandbox Code Playgroud)
  2. 但是我需要显示反向索引路径的注释(最新版本位于最底层).换句话说,在我需要使用的任何地方,indexPath我都使用:

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

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()
}
Run Code Online (Sandbox Code Playgroud)

它与我的问题有关吗?

bte*_*pot 6

编辑答案:

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

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

这种行为的来源需要进一步调查.

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

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