У меня есть Navigation Controller, который содержит uitableview, когда я нажимаю на строку, он вставляет новый контроллер представления в стек, который используется для отображения подробной информации в подробном представлении, которое он делает запрос от сервера, чтобы получить какой-то ответ затем, когда информация возвращается, я использую insertRowsAtIndexPaths:
для отображения информации, возвращаемой с сервера.
В первый раз все работает нормально, затем, когда я нажимаю кнопку "Назад" и выбираю новую строку или ту же строку для просмотра подробной информации, когда я вызываю insertRowsAtIndexPaths:
, я получаю следующую ошибку:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. 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 (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Вот код для переноса представления в стек:
VideoDetailViewController_iPhone *nextView = [[VideoDetailViewController_iPhone alloc] initWithNibName:@"VideoDetailViewController_iPhone" bundle:nil withVideo:rowData];
nextView.navController = navController;
[navController pushViewController:nextView animated:YES];
[nextView release];
Здесь код выполняется, как только информация возвращается с сервера
- (void)fetchVideoDetail:(NSNotification *)notification {
hasLoadedResponses = YES;
NSArray *obj = (NSArray *)[notification object];
responses = [[obj valueForKey:@"responses"] mutableCopy];
//NSLog(@"RESPONSES: %@", responses);
if ([responses count] == 0) {
[tblView reloadData];
return;
}
NSMutableArray *indexes = [[NSMutableArray alloc] init];
int i = 0;
for (NSArray *x in responses) {
if (i > 0) {
//The reason for skipping the first one is because we will change that row once the table refreshes we just need to insert any rows after the first one.
[indexes addObject:[NSIndexPath indexPathForRow:i inSection:1]];
}
i++;
}
//NSLog(@"indexCount: %i", [indexes count]);
[tblView beginUpdates];
[tblView insertRowsAtIndexPaths:indexes withRowAnimation:UITableViewRowAnimationBottom];
[tblView endUpdates];
//[tblView reloadData];
}
Вот методы tableView:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (section == 0) {
return 1;
} else {
if ([responses count] == 0) {
NSLog(@"numberofrowsinsection: 1");
return 1;
} else {
NSLog(@"numberofrowsinsection: %i", [responses count]);
return [responses count];
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
VideoCell *cell = (VideoCell *)[tableView dequeueReusableCellWithIdentifier:CellClassName];
if (cell == nil) {
NSArray *topLevelItems = [cellLoader instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
}
if (indexPath.section == 0) {
cell.lblTitle.text = [data title];
cell.lblDescription.text = [data videoDescription];
} else {
if ([responses count] == 0) {
if (!hasLoadedResponses) {
cell.lblTitle.text = @"";
cell.lblDescription.text = @"";
} else {
//Responses have been loaded
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.lblTitle.text = @"No responses to this video";
cell.lblDescription.text = @"Be the first to respond by selecting the \"Set as Destination\" button above";
}
} else {
//Display the response information
cell.lblTitle.text = [[responses objectAtIndex:indexPath.row] valueForKey:@"title"];
cell.lblDescription.text = [[responses objectAtIndex:indexPath.row] valueForKey:@"description"];
}
}
return cell;
}