2012-01-22 9 views
13

UITableViewから最後のレコードを削除すると、次のエラーが発生します。 (3)でなければならない更新後のセクション0の行の無効 数既存のセクションに含まれる行数を「無効な更新:キャッチされない例外により 「NSInternalInconsistencyException」、理由にアプリを終了最後のレコードを削除するとUITableView deleteRowsAtIndexPathがクラッシュする

更新(1)前のそのセクションに含まれる 行の数と等しいか、またはその部分(1が挿入された、1が挿入された が削除された)に挿入または削除された行の数プラスプラスマイナスの行数(0が移動し、0が移動した) のうち、

私の目標は、テーブル配列が空の場合は「レコードが見つかりません」を表示することです。

これは私が使用しているコードです。テーブル配列から最後のレコードを削除すると、アプリケーションがクラッシュします。どのようにしてテーブルを再読み込みし、 "No Record Found"ラベルを表示することができますか?

// 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]; 
     } 
    } 
} 
+0

たライン上のアプリがクラッシュしていますか?どのコンソールログですか? – sergio

+0

クラッシュログをお願いします。 - 編集:ああ、いいえ。それを見つけた。 –

+0

ありがとう、ニックネームクラッシュログ – Desmond

答えて

14

問題は、ビューで実行された操作がデータソースと一致することが予想されることです。テーブルに1つのレコードがあり、それを削除します。テーブルビューでは、データソースにゼロレコードが含まれていることが予想されますが、「レコードが見つかりません」というロジックのため、実際には値3が返されるため、整合性エラーとクラッシュします。

バグは、この部分のようだ:最後の行を削除しますが、あなたの「レコードなしので、発見されたとき、私はこれを挿入しないことを意図していたと仮定し

if ([idArray count] == 0) { 
    [self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
} 

表に行を「レコードが見つかりました」 「実際には3つの行にまたがる、あなたはこのように、代わりにここに3行を挿入する必要があります。

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

あなたはしかし、正気を所有するために、私は別のアプローチを提案することができますか?あなたのテーブルとデータソースを同期させようとするのではなく、表示目的のためにしか存在しないこれらの3行のデータをじゃまにしながら、UILabelを(テーブルビューの前か後ろの)ビュー階層に挿入して、テーブルがデータを持っているかどうかに基づいてそれを表示/非表示にしますか?そのようにすれば、データソースロジックを使いこなすことなく、その位置と外観を正確に制御することができます。行を削除するに対処するための

+0

ありがとう、ニック。私は試してみる – Desmond

+0

そう...それは動作しましたか? –

+0

それは特定の拡張で動作し、最後の行が削除されました...しかし、面白いバグを表示します。私は表示するためにURのアドバイスを取ることになり、UILabelはレコードが見つからなかった。 – Desmond

10

一般的なルールは以下のとおりです。行のアニメーション例えばので

であなたのモデルと

  1. ディール
  2. ディール:

    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    
        if (editingStyle == UITableViewCellEditingStyleDelete) { 
         NSInteger row = [indexPath row]; 
    
         [yourModel removeObjectAtIndex:row]; // you need to update your model 
    
         [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
        } 
    } 
    

    今、中私の意見では、正しいコードは次のようなものです(私はあなたを導くコメントを書いています)。

    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    
        if (editingStyle == UITableViewCellEditingStyleDelete) { 
         //Get the object to delete from the array. 
         identifyObject = [appDelegate.idArray objectAtIndex:indexPath.row]; 
         [appDelegate removeID:identifyObject]; // update model first 
    
         // now you can check model count and do what you want 
         if ([appDelegate.idArray count] == 0) // I think you mean appDelegate.idArray 
         { 
          // do what you want 
          // with [self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
         } 
    
         else 
         { 
          [self.idTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
         } 
        } 
    } 
    

    希望します。

2

私は「No rows」という警告にセルを使用したのと同じ方法を使用していました。私にとって

が、これは働いていた:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

if (editingStyle == UITableViewCellEditingStyleDelete) { 

    [favs removeObjectAtIndex:indexPath.section]; 

    if ([favs count] == 0) { 
     [tableView reloadRowsAtIndexPaths:[[NSArray alloc]initWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade]; 
     [tableView setEditing:NO animated:YES]; 

     // Remove Edit bar button item 
     self.navigationItem.rightBarButtonItem = nil; 
    } 
    else { 
     // Animate the deletion from the table. 
     [tableView deleteRowsAtIndexPaths:[[NSArray alloc]initWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade]; 
    } 
} 

}

+0

ありがとう、それは私のためにきれいに働いた... –

関連する問題