删除 Tableview NSFetchedResultsController 中的最后一节行
Posted
技术标签:
【中文标题】删除 Tableview NSFetchedResultsController 中的最后一节行【英文标题】:Deleting last section row in a Tableview NSFetchedResultsController 【发布时间】:2014-12-07 18:31:13 【问题描述】:我正在构建一个通用的 FetchedResultsController DataSource 类,用于我所有的 TableViewControllers,其中一些有多个部分,一些没有(像任何项目一样)。
问题是当 Fetched Results Controller 有多个部分时(sectionNameKeyPath 不为空),如果 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,@"");
【问题讨论】:
你的问题到底是什么? 抱歉,Milz,无意发布!现在是正确的。 【参考方案1】:如果你实施:
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
然后 FRC 将为您确定是否需要插入或删除部分。
【讨论】:
【参考方案2】:斯威夫特 5.1
我在处理 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
方法。这里
你要检查之前有多少项目
选定表视图的部分,然后删除单行或(如果
该部分只有一行 lew) 整个部分
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
【讨论】:
这是我现在正在遵循的解决方案.. 如果您已将实体分组并允许使用删除动画进行删除.. 正在寻找不使用全局变量的解决方案,遗憾的是这是唯一的方法似乎工作以上是关于删除 Tableview NSFetchedResultsController 中的最后一节行的主要内容,如果未能解决你的问题,请参考以下文章