2012-01-22 16 views
13

UITableView'dan son kaydı sildiğimde şu hatayı alıyorum. 'Geçersiz güncelleme:UITableView deleteRowsAtIndexPath son kaydı silerken çöküyor

nedeniyle akıl yakalanmamış istisna 'NSInternalInconsistencyException' için uygulamayı Sonlandırma satır geçersiz sayıda bölüm 0. bir mevcut bölümünde yer alan satır sayısını güncellemeden sonra (3) olmalıdır güncelleştirme (1), artı veya eksi 'dan önce bu bölümde yer alan satır sayısına eşit, bu bölümden eklenen veya silinen satırların sayısı (1 eklenen, 1 silindi) ve artı veya eksi satırlar içine taşındı veya dışında bu bölüm (0 taşındı, 0 taşındı).

Hedefim, tablo dizisi boşsa "Kayıt Bulunamadı" göstermektir.

Kullanmakta olduğum kod budur. Tablo dizisinden son kaydı sildiğimde uygulama çöküyor. Tabloyu yeniden yüklemek ve "Kayıt Bulunamadı" etiketi göstermek nasıl mümkün olabilir?

// 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

hangi hattı üzerinde uygulama çökme yapar? Hangi konsol günlüğü? – sergio

+0

Kilitlenme günlükleri lütfen. - DÜZENLEME: ah, hayır. Onu buldum. –

+0

Teşekkürler Güncelleme Kilitlenme günlüğü – Desmond

cevap

14

Sorun, bir tablo görünümünün, görünümde gerçekleştirilen işlemleri, veri kaynağına uyacak şekilde beklemesidir. Tabloda bir kaydın var ve siz onu kaldırın. Tablo görünümü, veri kaynağının artık sıfır kayıt içermesini beklemektedir, ancak "kayıt bulunamadı" mantığınız nedeniyle, aslında 3 değerini, dolayısıyla tutarlılık hatasını ve çökmenizi döndürür.

if ([idArray count] == 0) { 
    [self.idTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
} 
Ben son satırı silindiğinde bu tabloya "hiçbir kayıt bulunamadı" satır ekleyin amaçlı olduğunu varsayalım

ancak "hayır kayıtları beri bulundu:

hata bu parçası gibi görünüyor "aslında üç satır yayılan, böyle yerine burada üç satır eklemek gerekir:

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

sen ancak aklı kendi için, ben farklı bir yaklaşım önerebilirsiniz? Tablonuzu ve veri kaynağınızı senkronize olarak tutmak yerine, yalnızca görüntüleme amacıyla var olan bu sahte üç satırlık veriyi hokkabazlarken, neden bir UILabel'i görünüm hiyerarşisine (tablonun önündeki veya arkasındaki) ekleyemez? hiçbir kayıt bulunamadı ve tablonun herhangi bir veriye sahip olup olmadığına göre göster/gizle? Böylelikle veri kaynağı mantığınızla uğraşmak zorunda kalmadan pozisyonunu ve görünümünü hassas bir şekilde kontrol edebilirsiniz. satırları silme başa çıkmak için

+0

Teşekkürler, nick. Denedim – Desmond

+0

Yani ... işe yaradı mı? –

+0

belirli bir şekilde çalışır, son satır kaldırılır ... ama komik bir böcek gösterir. Ben göstermek için u tavsiye almak için UILabel ve kayıt bulunamadı. – Desmond

10

Genel kurallar şunlardır: satırın animasyon örneğin Yani

ile Modelinizle

  1. Deal
  2. Deal:

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

    Şimdi, içeri bence doğru kod aşağıdaki gibi olabilir (size rehberlik edecek bazı yorumlar yazdım).

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

    Yardım edin.

2

"Satır yok" uyarısı için bir hücre kullandığım yerde aynı yaklaşımı kullanıyordum.Benim için

, bu çalıştı:

- (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

Teşekkürler, benim için güzelce çalıştı ... –