7

Ich habe Schwierigkeiten bei der Implementierung 2 nsfetchedresultsController in einem tableView. Ich wollte einen fetchedresultsController in jedem Abschnitt der Tabelle (2 Teile), etwa so:
Mehrere NfetchedResultsController auf einem UItableView

Wunschliste

  • Produkt
  • product2

Gekauft

  • product3

Ich weiß, dass ich für dieses Beispiel würde 2 NSFetchedResultsController nicht brauchen, aber ich werde diese später brauchen ..

wenn ich ein Produkt entfernen von einem NSFetchedResultsController es auf die andere geht und ich diese Fehlermeldung erhalten:

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)"

ich denke dies geschieht, weil, wenn der erste fetchedRController eine Änderung erkennt er die Tableview, bevor der zweite aktualisiert genannt wird, ist das richtig? Soll ich NSMutableArrays verwenden und das TableView manuell aktualisieren?

Der Code:

- (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; 
    } 
} 
} 

Antwort

1

:) Sorry, Jungs, es war ein Noob-Fehler .. der Fehler passierte, weil der indexPath.section den Abschnitt in der TableView zurückgegeben hat, aber ich hatte keine Abschnitte in der abgerufenenResultsController (immer Index 0). BEARBEITEN: eigentlich gibt es einen ..

Nicht sicher, ob es der beste Weg ist, aber das Problem gelöst.
Thks!
Ricardo Castro

1

Verwenden von mehreren ist der falsche Ansatz. Die richtige Lösung besteht darin, den sectionNameKeyPath Parameter zu NSFetchedResultController zu verwenden, um die Ergebnisse in mehrere Abschnitte zu gruppieren, in Ihrem Fall wäre es eine gekaufte boolesche Eigenschaft auf dem Produkt. Und Sie sollten dies auch die erste Sortierung in aufsteigender Reihenfolge machen, da Sie oben erworbene nicht gekauft haben wollen.Verwenden Sie die Delegate-Methode für die Kopfzeilentiteltabelle, um die Strings "Wishlist" und "Purchased" für jeden Abschnittsindex zurückzugeben.

Wenn Sie denken, dass Sie vielleicht eine dritte Liste in der Zukunft haben, dann verwenden Sie besser eine numerische Statuseigenschaft und im Code eine Aufzählung für jeden Status (oder Listen), in dem das Produkt sein kann Das ist getan, anstatt auf einem Bool zu sortieren.