web-dev-qa-db-fra.com

Mise à jour non valide: nombre de lignes non valide dans la section

Je travaille sur un projet utilisant Microsoft Azure services. En ce que lors de la suppression d'une ligne, j'obtiens cette erreur:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (2) must be equal to the number of rows 
contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

Le code pour le chargement et la suppression de la table est le suivant:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    //medicine list
    if (section == 0) {
        NSArray *sectionInfo = [self.fetchedResultsController1 fetchedObjects];
        return [sectionInfo count];

    }
    //allergy list
    else if (section == 1) {
        NSArray *sectionInfo = [self.fetchedResultsController2 fetchedObjects];
        return [sectionInfo count];

    }
    //notes list
    else if (section == 2){
        NSArray *sectionInfo = [self.fetchedResultsController3 fetchedObjects];
        return [sectionInfo count];
    }
    else
        return 0;
 }

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *cellIdentifier = @"mcell";
    MedicationTableViewCell *cell = (MedicationTableViewCell *)    [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    //  Add utility buttons 
    NSMutableArray *rightUtilityButtons = [NSMutableArray new];
    [rightUtilityButtons sw_addUtilityButtonWithColor: [UIColor colorWithRed:1.0f green:0.231f blue:0.188 alpha:1.0f] title:@"Delete"];

    switch (indexPath.section) {
        case 0: {
            NSManagedObject *item = [self.fetchedResultsController1 objectAtIndexPath:indexPath];
            cell.textLabel.text = [item valueForKey:@"name"];
            break;
        }
        case 1: {
            NSManagedObject *item = [self.fetchedResultsController2 objectAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]];
            cell.textLabel.text = [item valueForKey:@"name"];
            break;
        }
        case 2: {
            NSManagedObject *item = [self.fetchedResultsController3 objectAtIndexPath: [NSIndexPath indexPathForRow:indexPath.row inSection:0]];
            cell.textLabel.text = [item valueForKey:@"title"];
            break;
        }
        default:
            break;
    }
    cell.rightUtilityButtons = rightUtilityButtons;
    cell.delegate = self;

    return cell;
}

- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index {

 // Delete button is pressed
 NSIndexPath *cellIndexPath = [self.medicationsTableView indexPathForCell:cell];

 //fetchingg data from local store first
 NSManagedObject *item = [self.fetchedResultsController1 objectAtIndexPath:[NSIndexPath indexPathForRow:cellIndexPath.row inSection:0]];

   NSMutableArray *keys = [[NSMutableArray alloc] initWithObjects:@"id", @"name", @"userId", nil];
   NSMutableArray *values = [[NSMutableArray alloc] initWithObjects: [item valueForKey:@"id"], [item valueForKey:@"name"], [item valueForKey:@"userId"], nil];

    //creating dictionary of data
    NSDictionary *dict = [[NSDictionary alloc] initWithObjects:values forKeys:keys];

    //calling delete fucntion
    [self.authService deleteItem:self.syncTable withDict:dict completion:^{
    //removing row from table view
    [self.medicationsTableView reloadData];
    [self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
      }];
      break;
}

Veuillez dire où je me trompe. Merci d'avance !!!!

7
user1722889

Dans - (void)swipeableTableViewCell: didTriggerRightUtilityButtonWithIndex:

Vous devez supprimer soit

[self.medicationsTableView reloadData]; 

ou

[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];

Parce que sur la première ligne lorsque reloadData est appelé, il recharge la table avec une nouvelle source de données et appelle de nouveau deleteRowsAtIndexPaths essaie de supprimer une ligne qui a déjà été supprimée en appelant reloadData plus tôt.

17
Tapas Pal

La chose importante est que vous devez utiliser soit

[self.medicationsTableView reloadData];

ou

[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];

La raison étant, lorsque le tableview's reload data est appelée la ligne qui est supprimée de la source de données est supprimée et après cela, lorsque l'api de la ligne de suppression est appelée pour la même index path (où la ligne est déjà supprimée provoque le problème)

Juste avant de supprimer la ligne du tableau, supprimez également l'objet de la source de données (self.fetchedResultsController1) et appelez

[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];

et une fois l'animation de suppression de la ligne ci-dessus terminée, vous pouvez appeler (mais ce n'est pas obligatoire)

[self.medicationsTableView reloadData];
11
Sanjay Mohnani