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

iOS-核心数据-表格视图滚动到新添加的记录,ios,uitableview,core-data,nsfetchedresultscontroller,Ios,Uitableview,Core Data,Nsfetchedresultscontroller,概述: 我在中有一个iOS项目,包含以下内容: 核心数据(使用NSFetchedResultsController) 在表视图中显示数据(UITableView) 我想做什么: 当用户添加记录时,我想滚动到新添加的记录 我所做的 - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)index

概述:

我在中有一个iOS项目,包含以下内容:

  • 核心数据(使用NSFetchedResultsController)
  • 在表视图中显示数据(
    UITableView
我想做什么:

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

- (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;
        }
    }
}
  • 添加新记录时,在
    NSFetchedResultsControllerDelegate
    方法中,当类型为insert/update/move时,我将索引路径存储在属性
    lastAddedIndexPath
  • 调用save后,我滚动到“lastAddedIndexPath”
  • 代码(NSFetchedResultsControllerDelegate)

    滚动代码

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

    • 我认为记录是在不同的线程中异步添加到表视图的
    • 因此,即使在保存数据库之后,当我滚动到
      lastAddedIndexPath
      时,表中的记录仍然不存在
    问题

  • 将记录添加到表视图后,如何滚动到新添加的记录路径
  • 我是否应该使用通知来知道何时保存数据库
  • 是否有其他替代方法

  • 您应该在以下位置执行滚动:

    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    

    或者,您可以使用KVO在添加新记录时收到通知。

    在我的场景中,我需要在表视图顶部显示最后添加的对象,因此我使用了不同的方法,我使用NSSortDescriptor对数组进行排序,然后在每次添加/删除任何记录时重新加载表视图。像这样

    NSSortDescriptor * sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO]autorelease];
    NSArray * sortDescriptorArray = [[[NSArray alloc] initWithObjects:sortDescriptor,nil]autorelease];
    
    self.commitsList =  [[self.listItem.itemCommit allObjects] sortedArrayUsingDescriptors:sortDescriptorArray];
    
    [tblView reloadData];
    
    然后,您可以在
    initWithKey
    中使用与数据相关的任何键,并对数组进行排序以解决此问题。
    在表格视图的
    CellForRowIndex
    方法中,您可以使用此数组填充表格视图。

    您的滚动必须在
    [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 
    
        } 
    } 
    

    您的[self.tableView endUpdates]电话在哪里?你希望在这之后滚动。我正在控制器IDChangeContent内执行滚动:我重新编辑了问题以显示代码。那么,如果你切换滚动并更新结束,会发生什么?太棒了!!!!!!!救了我一天谢谢你,我一整天都在伤着头。问题是,当一条新记录被添加到表视图的末尾时,indexPath.row大于[self.tableView numberofrowsinssection:indexPath.section],并导致了一个crashI,我会将其作为答案发布!谢谢,我正在ControllerdChangeContent内执行滚动:但似乎不起作用。已重新编辑问题以显示代码。让我试试KVO.Thank Shahid,但在我的例子中,我是根据不同的字段对其进行排序的,我无法更改排序顺序,所以我只想滚动到该记录。您可以使用此方法scrollToRowAtIndexPath:atScrollPosition:animated:并在此之前进行排序,您通常会这样做。它将指向您最近添加的行