UITableView
は、NSFetchedResultsController
によって管理されていますが、特定のCore Dataエンティティのすべてのインスタンスを表示します。tableView:アイテムを削除した後にnil indexPathを指定してcellForRowAtIndexPathを呼び出す
ユーザーがテーブルビューの項目をスワイプして削除すると、最終的にUITableViewController
にtableView:cellForRowAtIndexPath:
が呼び出され、nil
indexPath
と表示されます。私はそれがnil
indexPath
と呼ばれることを期待していなかったので、アプリがクラッシュします。
値がnil
であることを確認して空のセルを返すことで、クラッシュを回避できます。これはうまくいくようですが、私はまだ何か問題を処理している可能性があることを心配しています。何か案は?誰もがnil
indexPath
と呼ばれるtableView:cellForRowAtIndexPath:
を見たことがありますか?
これは、ユーザーがセルをスワイプしてテーブルビューから削除した場合にのみ発生することに注意してください。テーブルビュー編集モードを使用してアイテムを削除すると、そのアイテムは削除されません。セルを削除する2つの方法の違いは何ですか?
テーブルビューデリゲートメソッドでnil
indexPath
を取得するのは本当に問題ありませんか?
私のビューコントローラのコードは本当に標準です。ここでの削除は以下のとおりです。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.moc deleteObject:managedObject];
NSError *error = NULL;
Boolean success = [self.moc save:&error];
if (!success) { <snip> }
// actual row deletion from table view will be handle from Fetched Result Controller delegate
// [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else { <snip> }
}
これが呼び出されNSFetchedResultsController
デリゲートメソッドにつながる:
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeInsert: <snip> break;
case NSFetchedResultsChangeUpdate: <snip> break;
case NSFetchedResultsChangeMove: <snip> break;
}
}
そしてもちろん、データソースメソッドはNSFetchedResultsController
によって処理され、例えば:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
多くのありがとうございます。
をこれらFetchedResultsControllerデリゲートメソッドを持っていますか? – Mundi
'tableView:commitEditingStyle:forRowAtIndexPath'のテーブルビューで' reloadData'を呼び出すことをお勧めします。私はこれと同様の問題を抱えていて、それを固定したテーブルビューを再読み込みしました。 – Greg