2012-01-22 30 views
13

Tôi gặp phải lỗi sau khi tôi xóa bản ghi cuối cùng từ UITableView.UITableView xóaRowsAtIndexPath sự cố khi xóa bản ghi cuối

Chấm dứt ứng dụng do ngoại lệ uncaught 'NSInternalInconsistencyException', lý do: 'cập nhật không hợp lệ: không hợp lệ số hàng trong phần 0. Số lượng hàng chứa trong một phần hiện sau khi cập nhật (3) phải bằng số lượng hàng có trong phần đó trước khi cập nhật (1), cộng hoặc trừ số hàng được chèn hoặc xóa khỏi phần đó (1 được chèn, 1 bị xóa) và cộng hoặc trừ số hàng được chuyển vào hoặc ra khỏi phần đó (0 đã chuyển vào, 0 đã chuyển đi). '

Mục tiêu của tôi là hiển thị "Không tìm thấy bản ghi" nếu mảng bảng trống.

Đây là mã tôi đang sử dụng. Khi tôi xóa bản ghi cuối cùng khỏi mảng bảng, ứng dụng gặp sự cố. Làm cách nào để tải lại bảng và hiển thị nhãn "Không tìm thấy bản ghi"?

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

trên đó dòng hiện các vụ tai nạn ứng dụng? những gì giao diện điều khiển đăng nhập? – sergio

+0

Vui lòng ghi nhật ký sự cố. - EDIT: ah, không. Tìm thấy rồi. –

+0

Cảm ơn Cập nhật đăng nhập Crash – Desmond

Trả lời

14

Vấn đề là việc xem bảng dự kiến ​​các hoạt động được thực hiện trên dạng xem để khớp với nguồn dữ liệu. Bạn có một bản ghi trong bảng và bạn xóa nó. Bảng nhìn dự kiến ​​nguồn dữ liệu giờ đây chứa 0 bản ghi, nhưng vì logic "không tìm thấy bản ghi", nó thực sự trả về giá trị là 3, do đó lỗi nhất quán và sự cố của bạn.

Các lỗi có vẻ là phần này:

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

Tôi giả định này được dự định để chèn "không có hồ sơ tìm thấy" hàng vào bảng khi dòng cuối cùng sẽ bị xóa, nhưng vì "không có hồ sơ của bạn tìm thấy "thực sự trải dài ba hàng, bạn cần phải chèn ba hàng vào đây để thay thế, như sau:

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

Vì bạn sở hữu sanity, tôi có thể đề xuất một cách tiếp cận khác không? Thay vì cố gắng giữ cho bảng và nguồn dữ liệu của bạn đồng bộ hóa trong khi tung ra ba hàng dữ liệu giả mạo chỉ có mục đích hiển thị, tại sao không chỉ chèn UILabel vào hệ thống phân cấp của bạn (ở phía trước hoặc phía sau bảng nhìn). không tìm thấy bản ghi nào "và hiển thị/ẩn nó dựa trên việc liệu bảng có bất kỳ dữ liệu nào không? Bằng cách đó bạn có thể kiểm soát chính xác vị trí và diện mạo của nó mà không cần phải xoay quanh với logic nguồn dữ liệu của bạn.

+0

Cảm ơn, nick. Tôi sẽ thử là – Desmond

+0

Vì vậy ... nó đã làm việc? –

+0

nó hoạt động trong một số mở rộng nhất định, hàng cuối cùng bị loại bỏ ... nhưng hiển thị một lỗi hài hước. tôi kết thúc việc tư vấn cho bạn để hiển thị và UILabel không tìm thấy bản ghi nào. – Desmond

10

Quy tắc chung để đối phó với xóa hàng là:

  1. Deal với mô hình của bạn
  2. Deal với hình ảnh động hàng của

Vì vậy, ví dụ:

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

Bây giờ, trong ý kiến ​​của tôi đúng mã có thể là sau (tôi đã viết một số ý kiến ​​để hướng dẫn bạn).

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

Hy vọng điều đó sẽ hữu ích.

2

Tôi đã sử dụng cách tiếp cận tương tự, nơi tôi đã sử dụng ô cho cảnh báo "Không có hàng".

Đối với tôi, điều này làm việc:

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

Cảm ơn, nó đã làm việc cho tôi đẹp đẽ ... –

Các vấn đề liên quan