2

概述:

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

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

我想做的事:

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

我做了什么

  1. 添加新记录时,在方法内部,当类型为插入/更新/移动时NSFetchedResultsControllerDelegate,我将索引路径存储在属性中lastAddedIndexPath
  2. 调用保存后,我滚动到“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;
        }
    }
}

滚动代码

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

问题

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

问题

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

3 回答 3

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 

    } 
} 
于 2012-04-18T07:44:02.467 回答
1

您应该执行滚动:

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

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

于 2012-04-18T05:45:25.537 回答
0

在我的场景中,我需要在表格视图顶部显示最后添加的对象,因此我使用了不同的方法,我使用 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表格视图的方法中,您可以使用此数组来填充表格视图。

于 2012-04-18T06:10:57.000 回答