ViewController はUITableView
、NSFetchedResultsController を使用してアクセスしてCore Data
(SQLite) 表示します。ユーザーはスワイプして削除でき、追加されたアイテムが表示されます。すべてが期待どおりです。
UISearchBar
を使用して行をフィルタリングすると、 が新しいインスタンスに置き換えられ ますNSFetchedResultsController
。NSPredicate
ユーザー入力を表す が に設定されていることを除いて、同じです。NSFetchRequest
ユーザーがスワイプして行を削除するまで、すべて問題ありません。 commitEditingStyle
が発生し、オブジェクトが削除されます。didChangeObject
が発生し、deleteRowsAtIndexPaths
メソッドが実行されますが、今回は行は削除されません。
その後、物事は洋ナシの形になり始めます。ユーザーが再度行を削除しようとすると、アプリがスローします
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
***
そのため、tableView はそのインデックスにオブジェクトがないと認識しますが、表示されます。そうしないと、ユーザーはcommitEditingStyle
メソッドを呼び出すことができません。
deleteRowsAtIndexPaths を取得して行を視覚的に削除するにはどうすればよいですか?
ありがとうロブ
- (void) tableView:(UITableView *) tableView commitEditingStyle:(UITableViewCellEditingStyle) editingStyle forRowAtIndexPath:(NSIndexPath *) indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObject *objectToDelete = [fetchedResultsController objectAtIndexPath:indexPath];
[moc deleteObject:objectToDelete];
[moc save:nil];
[self saveData];
}
}
- (void) saveData
{
NSError *error = nil;
[moc save:&error];
if(kGlobalRunLogging && error)
NSLog(@"Failed to save data") ;
}
- (void) controller:(NSFetchedResultsController *) controller didChangeObject:(id) anObject
atIndexPath:(NSIndexPath *) indexPath forChangeType:(NSFetchedResultsChangeType) type newIndexPath:(NSIndexPath *) newIndexPath
{
switch(type) {
case NSFetchedResultsChangeUpdate:
//Boring cell formatting stuff
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
最後に、NSFetchedResultsController を返すメソッド
- (NSFetchedResultsController *) fetchedResultsControllerWithPredicate:(NSPredicate *) aPredicate
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Product" inManagedObjectContext:moc]];
[request setPredicate:aPredicate];
NSSortDescriptor *namesDescriptor = [[NSSortDescriptor alloc] initWithKey:@"initial" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObjects:namesDescriptor, nil]];
NSString *cacheName = @"Root";
if(aPredicate) cacheName = nil;
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:@"initial" cacheName:cacheName];
aFetchedResultsController.delegate = self;
NSError *anyError = nil;
if (![aFetchedResultsController performFetch:&anyError]) {
NSLog(@"Error fetching: %@", anyError) ;
}
return aFetchedResultsController;
}