2010-10-30 25 views
8

Tôi có một UITableView hiển thị danh sách các đối tượng được lưu trữ với CoreData. Tôi có thể xóa đối tượng bằng cách sử dụng mã sau:Xóa hàng hoạt ảnh trong UITableView với CoreData cho lỗi xác nhận

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
if (editingStyle == UITableViewCellEditingStyleDelete) { 
    NSLog(@"Delete row"); 
    [managedObjectContext deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]]; 

    // Save the context. 
    NSError *error; 
    if (![managedObjectContext save:&error]) { 
     /*do this gracefully one day */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
    [self refreshTables]; //where refreshTables just reloads the data the table is using and calls [self.tableView reloadData]; 
} 

} 

Nhưng nó không có hoạt ảnh hoặc thẩm mỹ.

Khi tôi cố gắng động bằng cách thay thế

[self refreshTables]; 

với

[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 

tôi nhận được lỗi sau:

Assertion failure in -[UITableView _endCellAnimationsWithContext:], >/SourceCache/UIKit_Sim/UIKit-1261.5/UITableView.m:920 2010-10-30 16:46:35.717 MyApp[38226:207] * 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 (3), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'

tôi đã cố gắng có deleteRowsAtIndexPaths mã trong một loạt các địa điểm trong mã commitEditingStyle không có lu ck (ví dụ trước khi loại bỏ các đối tượng từ mOC) nhưng tôi không thể có vẻ để có được xung quanh lỗi này.

Tôi biết ví dụ iPhoneCoreDataRecipes của Apple xử lý sự cố bằng cách thiết lập đại biểu cho FetchedResultsController để xử lý chỉnh sửa/xóa hàng, nhưng ở giai đoạn này trong phát triển, nếu có thể, tôi chỉ muốn một giải pháp đơn giản cho hoạt ảnh.

Làm cách nào để tạo hiệu ứng cho việc xóa một hàng, trước/sau khi tôi xóa đối tượng khỏi managedObjectContext của mình?

EDIT: Tôi đã thử xóaRowsAtIndexPaths trước và sau khi xóa mục khỏi mOC, với cùng một lỗi.

Trả lời

7

1) Tôi thiết lập đại biểu chính xác.

2) Tôi đã xóa một cuộc gọi trong chế độ xemWillLoad thành [self.tableview reloadData]; đó là (kỳ quặc) lộn xộn tất cả mọi thứ lên (bài đăng này đã cho tôi một đầu mối cho những gì để tìm kiếm và loại bỏ: Serious Application Error in Core Data with fetchedResultsContainer).

+0

# 2 đã khắc phục được sự cố của tôi. Cảm ơn! –

-2
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
     if (editingStyle == UITableViewCellEditingStyleDelete) { 
      NSLog(@"Delete row"); 

    // Delete the row first 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 

    //Then delete the object. 
      [managedObjectContext deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]]; 

      // Save the context. 
      NSError *error; 
      if (![managedObjectContext save:&error]) { 
       /*do this gracefully one day */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 
     } 


    } 
+0

Không, điều đó không làm việc. Tôi đã thử trước khi đăng. Lỗi tương tự: Lỗi xác nhận trong - [UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1261.5/UITableView.m:92 – glenstorey

0

Bạn đang sử dụng NSFetchedResultsController chưa?
Bạn nhận được lỗi này bởi vì đối tượng vẫn còn trong nguồn dữ liệu tableview của bạn.

Có thể at this stage in development bạn đang sử dụng simple solution và điền NSArrays với các đối tượng từ NSFetchRequest. Sau đó, sẽ vô ích khi xóa đối tượng khỏi ngữ cảnh đối tượng được quản lý


bạn đang sử dụng bộ nhớ cache cho NSFetchedResultsController? Tôi chỉ có một cái nhìn khác trong tài liệu và tìm thấy điều này:

A controller thus effectively has three modes of operation, determined by whether it has a delegate and whether the cache file name is set.

No tracking: the delegate is set to nil. The controller simply provides access to the data as it was when the fetch was executed.

Memory-only tracking: the delegate is non-nil and the file cache name is set to nil. The controller monitors objects in its result set and updates section and ordering information in response to relevant changes.

Full persistent tracking: the delegate and the file cache name are non-nil. The controller monitors objects in its result set and updates section and ordering information in response to relevant changes. The controller maintains a persistent cache of the results of its computation.

Vì vậy, chế độ của bộ điều khiển là "Không theo dõi". Điều đó có nghĩa là các đối tượng không được gỡ bỏ khỏi bộ điều khiển nếu chúng bị loại bỏ khỏi đối tượng được quản lý.
Điều gì có nghĩa là just reloads the data trong mã số refreshTables? Cố gắng làm tương tự trước khi xóa các hàng.
Hoặc thêm 20 dòng cần thiết đó để giúp người được ủy quyền làm việc.

+0

Tôi đang sử dụng NSFetchedResultsController và nguồn dữ liệu lõi không có vấn đề gì. Mã sans-animation loại bỏ thành công đối tượng coredata. Nó chỉ là hình ảnh động gây ra rắc rối. – glenstorey

+0

@glenstorey Tôi đoán tôi đã không đọc kỹ câu hỏi của bạn lần đầu tiên, hãy xem chỉnh sửa của tôi. –

17

Khi chúng tôi sử dụng NSFetchedResultsController làm nguồn dữ liệu của UITableView, chúng tôi không thể gọi deleteRowsAtIndexPaths: withRowAnimation: trong chức năng tableView: commitEditingStyle: forRowAtIndexPath:, sẽ ném ngoại lệ như câu hỏi được đề cập.

Một cách để giải quyết vấn đề này là bằng cách gọi [self.tableView reloadData] trong controllerDidChangeContent: từ giao thức NSFetchedResultsControllerDelegate. Nó thực sự giải quyết, tuy nhiên, không có Delete Fade Animation nữa.

Vì vậy, cách thuận tiện thay thế là bằng cách gọi [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade] trong controller: didChangeObject: atIndexPath: forChangeType: newIndexPath:.

Mẫu mã như sau:


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
    forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Delete NSManagedObject 
    NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath]; 
    [context deleteObject:object]; 

    // Save 
    NSError *error; 
    if ([context save:&error] == NO) { 
     // Handle Error. 
    } 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
     atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
     newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    if (type == NSFetchedResultsChangeDelete) { 
     // Delete row from tableView. 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
           withRowAnimation:UITableViewRowAnimationFade]; 
    } 
} 
+0

Điều này làm việc cho tôi ... câu trả lời tuyệt vời cho một bực bội "muộn vào buổi tối" loại vấn đề! – seanicus

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