我正在构建一个通用的FetchedResultsController DataSource类,用于我的所有TableViewControllers,其中一些有多个部分,有些没有(像任何Project一样)。
问题是当Fetched Results Controller有多个部分( sectionNameKeyPath 不为null)时,如果TableView部分只有一行,didChangeObject上的删除逻辑必须删除整个部分,但是如果在Fetched Results Controller定义(sectionNameKeyPath = nil)上只设置了一个部分,则相同的逻辑不起作用。
任何人都知道如何在didChangeObject上实现泛型删除逻辑以防止出现这种错误?
例外:
从代表处获取了一个例外 NSFetchedResultsController在调用期间 -controllerDidChangeContent :.无效更新:无效的节数。表视图中包含的节数 更新(1)必须等于包含的部分数 更新前的表视图(1),加号或减号 插入或删除的部分(0插入,1删除)。用户信息 (空)
//Fetched Results Controller Definition on My Model Class
+ (NSFetchedResultsController*)fetchedResultsController
{
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:[self.class entityName]];
//request.predicate = [NSPredicate predicateWithFormat:@"parent = %@", self];
request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"dueDate" ascending:NO]];
[request setFetchLimit:50];
//Generate an error
return [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:Store.defaultManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
//Works Fine
//return [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:Store.defaultManagedObjectContext sectionNameKeyPath:@"shortDueDate" cacheName:nil];
}
//Fetched Results Controller Generic Data Source Class
- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
if (type == NSFetchedResultsChangeInsert) {
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
} else if (type == NSFetchedResultsChangeMove) {
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
} else if (type == NSFetchedResultsChangeDelete) {
BOOL deleteSection = FALSE;
//If have only one section and its the last row then delete entire section
if ((self.tableView.numberOfSections == 1) && ([self.tableView numberOfRowsInSection:[indexPath section]] == 1 )) {
deleteSection = TRUE;
}
if (deleteSection) {
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:YES];
} else {
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
} else {
NSAssert(NO,@"");
}
}
答案 0 :(得分:1)
如果您实施:
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
然后FRC将为您确定是否需要插入或删除部分。
答案 1 :(得分:0)
在处理NSFEtchedResultsController和CoreData时,我遇到了类似的问题。
覆盖func tableView(_:, commit:, forRowAt:)
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let commit = fetchedResultsController.object(at: indexPath)
let sections = fetchedResultsController.sections
let section = sections![indexPath.section]
// numberOfObjectsInCurrentSection is the class' variable
numberOfObjectsInCurrentSection = section.numberOfObjects
container.viewContext.delete(commit)
saveContext()
}
}
实施此NSFetchedResultsControllerDelegate
方法。这里
您将检查以前剩余的项目数
所选表格视图的部分,然后删除一行或(如果
该部分只有一行左右)
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .delete:
tableView.beginUpdates()
if numberOfObjectsInCurrentSection! > 1 {
tableView.deleteRows(at: [indexPath!], with: .automatic)
} else {
let indexSet = NSMutableIndexSet()
indexSet.add(indexPath!.section)
tableView.deleteSections(indexSet as IndexSet, with: UITableViewRowAnimation.fade)
}
tableView.endUpdates()
default:
break
}
}