1

私の iPhone アプリには、(a) NSFetchedResultsController を更新し続けるための機能、(b) 複数のセクション、(c) アイテムを追加および削除する機能など、すべての「機能」を使用する (グループ化されていない) UITableView があります。 、および (d) UISearchDisplayController を使用して、ユーザーがリストを検索できるようにします。リストは非常に長くなる可能性があります。

ユーザーが検索中にアイテムを削除しようとすると、問題が発生します。このエラーが発生しています:Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (21), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null)

アプリが検索モードに切り替わると、通常のセクション数 (アルファベット順、AZ) ではなく、単一のセクション (「検索結果」) に切り替わるという事実から問題が発生しているようです。そのため、アイテムを削除しようとするとき、単純に 1 つのセクション (検索結果) 内にある場合は、セクションの数が多いほど適切なセクション数であると考えています。

フェッチされた結果コントローラーを管理するための私のコードは次のとおりです。この種のアクションを処理する適切な方法を知っていますか?

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// if (!self.searchDisplayController.isActive) {
  [self.tableView beginUpdates];
// }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:

   [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
   break;

        case NSFetchedResultsChangeUpdate:
   if (!self.searchDisplayController.isActive) {
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
   } else {
   // I currently don't do anything if the search display controller is active, because it is throwing similar errors.
   }
   break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// if (!self.searchDisplayController.isActive) {
  [self.tableView endUpdates];
// }
}
4

1 に答える 1

1

NSFetchedResultsControllerがある場合は、述語を作成して、それをフィルターとしてコントローラーに設定してみませんか?

このようなもの:

NSPredicate *predicate =[NSPredicate predicateWithFormat:@"name contains[cd] %@", searchText];
[fetchedResultsController.fetchRequest setPredicate:predicate];

NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        // Fail
}           

[self.tableView reloadData];
于 2010-12-06T23:21:14.857 に答える