当我从 UITableView
中删除最后一条记录时遇到以下错误。
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 (3) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (1 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
我的目标是在表格数组为空时显示“未找到记录”。
这是我正在使用的代码。当我从表数组中删除最后一条记录时,应用程序崩溃了。如何重新加载表格并显示“未找到记录”标签?
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([idArray count]==0) {
return 3;
}
else
{
return [idArray count];
}
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"array count %d",[idArray count]);
if ([idArray count] == 0) {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.textAlignment = UITextAlignmentCenter;
tableView.userInteractionEnabled = NO;
self.navigationItem.leftBarButtonItem.enabled = NO;
NSUInteger row = [indexPath row];
switch (row) {
case 0:
cell.textLabel.text = @"";
break;
case 1:
cell.textLabel.text = @"";
break;
case 2:
cell.textLabel.text = @"No Records Found";
break;
default:
break;
}
return cell;
}
else
{ static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
tableView.userInteractionEnabled = YES;
self.navigationItem.leftBarButtonItem.enabled = YES;
// Set up the cell
identify *idItems = [idArray objectAtIndex:indexPath.row];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"dd MMM,yyyy"];
NSString *dateStr = [formatter stringFromDate:idItems.Date];
UIImageView *accDis = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Arrow.png"]];
cell.accessoryView = accDis;
self.idTableView.separatorColor = [UIColor colorWithRed:150.0/255.0 green:150.0/255.0 blue:150.0/255.0 alpha:1];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:18];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.detailTextLabel.textColor = [UIColor colorWithRed:100.0/255.0 green:100.0/255.0 blue:100.0/255.0 alpha:1];
cell.detailTextLabel.font = [UIFont italicSystemFontOfSize:16];
cell.detailTextLabel.adjustsFontSizeToFitWidth = YES;
NSString *detailText = [NSString stringWithFormat:@"%@ - %@",dateStr,idItems.GeoCode];
if (idItems.Image == NULL) {
cell.imageView.image = [UIImage imageNamed:@"icon58x58.png"];
}
else
{
//pass image to fix size 50 X 50
//UIImage *newImage = [self postProcessImage:idItems.Image];
cell.imageView.image = idItems.thumb;//newImage;
cell.imageView.contentMode=UIViewContentModeScaleAspectFill;
}
cell.textLabel.text = idItems.TypeName;
cell.detailTextLabel.text = detailText;
return cell;
}
}
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
if ([idArray count] >=1)
{
[idTableView beginUpdates];
//Get the object to delete from the array.
identifyObject = [appDelegate.idArray objectAtIndex:indexPath.row];
//Delete the object from the table.
[self.idTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[appDelegate removeID:identifyObject];
if ([idArray count] == 0) {
[self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
[idTableView endUpdates];
}
}
}
最佳答案
问题在于 TableView 期望在 View 上执行的操作与数据源相匹配。您在表中有一条记录,然后将其删除。 tableview 期望数据源现在包含零条记录,但由于您的“未找到记录”逻辑,它实际上返回值 3,因此出现一致性错误和崩溃。
错误似乎是这部分:
if ([idArray count] == 0) {
[self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
我假设这是为了在删除最后一行时将“未找到记录”行插入到表中,但是由于您的“未找到记录”实际上跨越三行,因此您需要在此处插入三行,例如这个:
if ([idArray count] == 0) {
[self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:
[NSIndexPath indexPathForRow:0 inSection:indexPath.section],
[NSIndexPath indexPathForRow:1 inSection:indexPath.section],
[NSIndexPath indexPathForRow:2 inSection:indexPath.section],
nil] withRowAnimation:UITableViewRowAnimationFade];
}
然而,为了您的理智,我可以建议一种不同的方法吗?与其试图让你的表和数据源保持同步,同时处理这些仅用于显示目的的假三行数据,不如将 UILabel 插入到你的 View 层次结构中(在 TableView 的前面或后面),上面写着“no records found”并根据表是否有数据显示/隐藏?这样你就可以精确地控制它的位置和外观,而不必搞砸你的数据源逻辑。
关于iphone - 删除最后一条记录时 UITableView deleteRowsAtIndexPath 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8960037/