Cómo filas adecuadamente eliminar en UITableView (controlado por NSFetchedResultsController) y al mismo tiempo la utilización de UISearchDisplayController?

StackOverflow https://stackoverflow.com/questions/4102865

Pregunta

En mi aplicación para el iPhone, tengo una (no agrupados) UITableView que utiliza todas las "campanas y silbatos", incluyendo (a) NSFetchedResultsController mantenerlo actualizado, (b) múltiples secciones, (c) la posibilidad de añadir y artículos de borrado, y (d) la UISearchDisplayController para permitir al usuario buscar por la lista, que puede llegar a ser muy largo.

Estoy corriendo en problemas cuando los intentos de usuario para eliminar elementos mientras están en el proceso de búsqueda. Estoy consiguiendo este error: 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)

Parece que el problema surge del hecho de que cuando la aplicación cambia al modo de buscar, en lugar del número habitual de secciones (que son por orden alfabético, A-Z), se cambia a una sola sección ( "Resultados de búsqueda"). Por lo tanto, cuando se trata de eliminar el elemento, se piensa que el número adecuado de secciones es el número más grande cuando se trata simplemente de una sola sección (los resultados de búsqueda).

Aquí está mi código para gestionar el controlador resultados inverosímiles. ¿Usted sabe cuál es la forma correcta de manejar este tipo de acciones?

- (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];
// }
}
¿Fue útil?

Solución

Si usted tiene una NSFetchedResultsController, ¿por qué no acaba de crear un predicado y lo puso en el controlador como un filtro?

Algo como esto:

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];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top