我有UITableViewController
子类并实现了以下
NSFetchedResultsController
及其代表tableView:sectionForSectionIndexTitle:atIndex:
tableView:titleForHeaderInSection:
在controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
在给定实体的数据模型中,我有临时属性uppercaseFirstLetterOfName
,它将返回持久属性的第一个字母。
这就是实现表项和侧索引的按字母顺序排列的部分。
现在,如果我有一个部分的单个记录,那么我重命名它以便它将更改部分,我得到以下异常,这发生在NSFetchedResultsChangeMove
之后的某个地方。
***断言失败 - [UITableView _endCellAnimationsWithContext:],/ SourceCache / UIKit_Sim / UIKit-984.38 / UITableView.m:774
Core Data期间发现了异常 更改处理:无效更新: 第0节中的行数无效。 包含的行数 更新后的现有部分(1) 必须等于行数 包含在该部分之前 更新(1),加号或减号 从中插入或删除的行数 部分(0已插入,1已删除)。
有什么想法吗?
UPD更多代码:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger count = [[fetchedResultsController sections] count];
return count;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
NSInteger numberOfRows = 0;
if ([[fetchedResultsController sections] count] > 0)
{
id <NSFetchedResultsSectionInfo> sectionInfo =
[[fetchedResultsController sections] objectAtIndex:section];
numberOfRows = [sectionInfo numberOfObjects];
}
return numberOfRows;
}
...
NSSortDescriptor* sortByWordDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"subject" ascending:YES];
NSArray* sortArray = [[NSArray alloc]
initWithObjects:sortByWordDescriptor, nil];
[fetchRequest setSortDescriptors:sortArray];
NSFetchedResultsController* controller = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"uppercaseFirstLetterOfName"
cacheName:@"Root"];
UPD(修补): 目前我修改了这样的代码:
case NSFetchedResultsChangeMove:
NSUInteger tableSectionCount = [self.tableView numberOfSections];
NSUInteger modelSectionCount = [[controller sections] count];
if (modelSectionCount > tableSectionCount)
{
[self.tableView insertSections:[NSIndexSet
indexSetWithIndex:[newIndexPath section]]
withRowAnimation:UITableViewRowAnimationNone];
}
else if(modelSectionCount < tableSectionCount)
{
if (tableSectionCount > 1)
{
[self.tableView deleteSections:[NSIndexSet
indexSetWithIndex:[indexPath section]]
withRowAnimation:UITableViewRowAnimationNone];
}
}
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
到目前为止还没有崩溃,但这是正确的解决方案吗?
答案 0 :(得分:2)
我想我知道你发生了什么事。确保你有:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
文档说明了“beginUpdates”方法:
如果要同时为后续插入,删除和选择操作(例如,cellForRowAtIndexPath:和indexPathsForVisibleRows)设置动画,请调用此方法。
这就是你正在做的事情:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
干杯
答案 1 :(得分:0)
处理这些部分的代码会期望某个项目位于某个索引但该项目不再存在,并且当没有项目时返回nil时,您似乎没有为该场景编码。< / p>
答案 2 :(得分:0)
在执行tableView的任何insert或delete方法之前,你应该修改数据源数组。
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
和NSFetchedResultsChangeMove
应该完成您的UI移动操作。
所以你需要做的是重新排序datasorce项目。