Microsoft Azure services
を使用してプロジェクトに取り組んでいます。行を削除しているときに、次のエラーが発生します。
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).
テーブルのロードおよび削除行のコードは次のとおりです。
- (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;
}
どこがいけないのか教えてください。よろしくお願いします!!!!
- (void)swipeableTableViewCell: didTriggerRightUtilityButtonWithIndex:
どちらかを削除する必要があります
[self.medicationsTableView reloadData];
または
[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
最初の行でreloadData
が呼び出されると、テーブルビューが新しいデータソースでリロードされ、再度deleteRowsAtIndexPaths
を呼び出すと、以前にreloadData
を呼び出して削除した行が削除されます。
重要なことは、どちらかを使用する必要があるということです
[self.medicationsTableView reloadData];
または
[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
その理由は、tableview's reload data
が呼び出されると、データソースから削除された行が削除され、その後、同じindex path
に対して行削除APIが呼び出されると、(行がすでに削除されているため、問題)
また、テーブルから行を削除する直前に、データソース(self.fetchedResultsController1
)からオブジェクトを削除し、呼び出します
[self.medicationsTableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationRight];
上記の行の削除アニメーションが完了した後、呼び出すことができます(ただし、必須ではありません)
[self.medicationsTableView reloadData];