iOS - 核心数据 - 表格视图滚动到新添加的记录

use*_*037 2 core-data uitableview nsfetchedresultscontroller ios

概述:

我有一个iOS项目,其中包括:

  • 核心数据(使用NSFetchedResultsController)
  • 在表视图中显示数据(UITableView)

我想做的事:

  • 当用户添加记录时,我想滚动到新添加的记录.

我做了什么

  1. 添加新记录时,在NSFetchedResultsControllerDelegate方法内部,lastAddedIndexPath当类型为insert/update/move时,我将索引路径存储在属性中
  2. 在调用save之后,我滚动到"lastAddedIndexPath"

代码(NSFetchedResultsControllerDelegate)

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{       
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    {
        switch(type)
        {
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                NSLog(@"going to store insert - scroll");
                self.lastAddedIndexPath = newIndexPath;
                break;

            case NSFetchedResultsChangeDelete:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                NSLog(@"going to store update - scroll");
                self.lastAddedIndexPath = newIndexPath;
                break;

            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                NSLog(@"going to store move - scroll");
                self.lastAddedIndexPath = newIndexPath;
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要滚动的代码

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if (self.beganUpdates) //already [self.tableView beginUpdates] invoked
    {
        [self scrollToLastAddedIndexPath];  //contains the logic to scroll
        [self.tableView endUpdates];   
    }
}
Run Code Online (Sandbox Code Playgroud)

问题

  • 我认为该记录是在另一个线程中异步添加到表视图中的.
  • 所以即使在保存数据库之后,当我滚动到lastAddedIndexPath表中的记录时还不存在.

问题

  1. 将记录添加到表视图后,如何能够滚动到新添加的记录路径?
  2. 我应该使用通知来了解数据库的保存时间吗?
  3. 还有其他替代方法吗?

jrt*_*ton 5

您的滚动必须发生在此之后,[self.tableView endUpdates]因为新行未添加到表中.所以切换两个语句:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
    if (self.beganUpdates) //already [self.tableView beginUpdates] invoked 
    { 
        [self.tableView endUpdates]; 
        [self scrollToLastAddedIndexPath];  //contains the logic to scroll 

    } 
} 
Run Code Online (Sandbox Code Playgroud)