iOS-核心数据-表格视图滚动到新添加的记录
概述: 我在中有一个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
- 核心数据(使用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
中- (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:并在此之前进行排序,您通常会这样做。它将指向您最近添加的行