7

Tengo dificultades para implementar 2 nsfetchedresultsController en un tableView. Yo quería un fetchedresultsController en cada sección de la mesa (2 secciones), algo como esto:
Multiple NsfetchedResultsController en un UItableView

Lista

  • producto
  • producto2

Comprado

  • product3

Sé que para este ejemplo no necesitaría 2 nsfetchedResultsController pero necesitaré esto más adelante ..

cuando quito un producto de uno nsfetchedResultsController pasa a la otra y me sale este error:

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted). with userInfo (null)"

que piensa que esto ocurre porque cuando la primera fetchedRController detecta un cambio actualiza el tableView antes de que el segundo se llama es así? ¿Debo usar NSMutableArrays y actualizar TableView manualmente?

El código:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
NSInteger numberOfRows = 0; 

switch (section) 
{ 
    case WISHLIST_SECTION: 

    { 
     numberOfRows =[[fetchedResultsControllerwish fetchedObjects]count]; 


    }; 
     break; 

    case PURCHASED_SECTION: 
    { 
     numberOfRows =[[fetchedResultsControllerPurchased fetchedObjects]count]; 

    }; 
     break; 


    default: 
     break; 
} 
return numberOfRows; 
} 

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
// The fetch controller is about to start sending change notifications, so prepare the table view for updates. 
[self.tableView beginUpdates]; 
} 


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 

// The fetch controller has sent all current change notifications, so tell the table view to process all updates. 
[self.tableView endUpdates]; 
} 

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

UITableView *tableViewT = self.tableView; 

switch(type) { 

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

    case NSFetchedResultsChangeDelete: 
     [tableViewT deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeUpdate: 
     [self configureCell:(GiftEventTableViewCell *)[tableViewT cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
     break; 

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

-(void)configureCell:(GiftEventTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 
switch (indexPath.section) { 
    case WISHLIST_SECTION: 
    { 
     GiftEvent *giftEv=(GiftEvent *)[fetchedResultsControllerwish objectAtIndexPath:indexPath]; 
     cell.gift=giftEv; 

    }; 
     break; 
    case PURCHASED_SECTION: 
    { 
     GiftEvent *giftEv=(GiftEvent *)[fetchedResultsControllerPurchased objectAtIndexPath:indexPath]; 

     //if i don't use indexpath.row in the second section i get an out of bounds error 
     //GiftEvent *giftEv=(GiftEvent *)[[fetchedResultsControllerPurchased fetchedObjects]objectAtIndex: indexPath.row]; 
     cell.gift=giftEv; 

    }; 
     break; 




    default: 
     break; 
} 

} 

// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
if (editingStyle == UITableViewCellEditingStyleDelete) 
{ 
    switch (indexPath.section) { 
     case WISHLIST_SECTION: 
     { 
      // Delete the managed object for the given index path 

      [self.managedObjectContext deleteObject:[fetchedResultsControllerwish objectAtIndexPath:indexPath]]; 

      // Save the context. 
      NSError *error; 
      if (![self.managedObjectContext save:&error]) { 
       /* 
       Replace this implementation with code to handle the error appropriately. 

       abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
       */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 
      [self.tableView reloadData]; 

      }; 
      break; 
     case PURCHASED_SECTION: 
     { 
      // Delete the managed object for the given index path 

      [self.managedObjectContext deleteObject:[fetchedResultsControllerPurchased objectAtIndexPath:indexPath]]; 

      // Save the context. 
      NSError *error; 
      if (![self.managedObjectContext save:&error]) { 
       /* 
       Replace this implementation with code to handle the error appropriately. 

       abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
       */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 

     }; 
      break; 

     default: 
      break; 
    } 
} 
} 

Respuesta

1

:) lo siento muchachos, era un error novato ... el error estaba ocurriendo porque indexPath.section devolvió la sección en el tableView pero no tenía secciones en el fetchedResultsController (siempre el índice 0). EDITAR: en realidad hay uno ..

NSIndexPath *indexPathTemp = [NSIndexPath indexPathForRow:indexPath.row inSection:0]; 

No estoy seguro de si es la mejor manera, pero resolvió el problema.
¡Gracias!
Ricardo Castro

1

El uso de múltiples es un enfoque incorrecto. La solución correcta es usar el parámetro sectionNameKeyPath en el NSFetchedResultController para agrupar los resultados en varias secciones, en su caso sería una propiedad booleana comprada en el producto. Y también debe hacer que este sea el primer descriptor de ordenación en orden ascendente, ya que desea comprar comprado anteriormente.Utilice el método delegado de la tabla de títulos del encabezado para devolver las cadenas "Lista de deseos" y "Comprado" para cada índice de sección.

Si cree que podría tener una tercera lista en el futuro, entonces sería mejor usar una propiedad de estado numérico, y en código una enumeración para cada uno de los estados (o listas) en que puede estar el producto. Por lo general, esto se hace en lugar de clasificar en un bool.

Cuestiones relacionadas