7

Tôi đang gặp khó khăn khi triển khai 2 nsfetchedresultsController trong một tableView. Tôi muốn có một fetchedresultsController trong mỗi phần của bảng (2 phần), một cái gì đó như thế này:
Nhiều NsfetchedResultsController trên UItableView

Danh sách mong ước

  • sản phẩm
  • PRODUCT2

Mua

  • product3

Tôi biết rằng ví dụ này tôi sẽ không cần 2 nsfetchedResultsController nhưng tôi sẽ cần sau này ..

khi tôi loại bỏ một sản phẩm từ một nsfetchedResultsController nó đi đến đầu kia và tôi nhận được lỗi này:

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted). with userInfo (null)"

Tôi nghĩ điều này xảy ra vì khi lần đầu tiên fetchedRController phát hiện thay đổi, bản cập nhật bảng trước khi lần thứ hai được gọi là đúng? sao tôi nên sử dụng NSMutableArrays và cập nhật tableView theo cách thủ công?

Mã:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
NSInteger numberOfRows = 0; 

switch (section) 
{ 
    case WISHLIST_SECTION: 

    { 
     numberOfRows =[[fetchedResultsControllerwish fetchedObjects]count]; 


    }; 
     break; 

    case PURCHASED_SECTION: 
    { 
     numberOfRows =[[fetchedResultsControllerPurchased fetchedObjects]count]; 

    }; 
     break; 


    default: 
     break; 
} 
return numberOfRows; 
} 

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
// The fetch controller is about to start sending change notifications, so prepare the table view for updates. 
[self.tableView beginUpdates]; 
} 


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 

// The fetch controller has sent all current change notifications, so tell the table view to process all updates. 
[self.tableView endUpdates]; 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 
    atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 
    newIndexPath:(NSIndexPath *)newIndexPath { 

UITableView *tableViewT = self.tableView; 

switch(type) { 

    case NSFetchedResultsChangeInsert: 
     [tableViewT insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeDelete: 
     [tableViewT deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeUpdate: 
     [self configureCell:(GiftEventTableViewCell *)[tableViewT cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
     break; 

    case NSFetchedResultsChangeMove: 
     [tableViewT deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
     [tableViewT insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
         withRowAnimation:UITableViewRowAnimationFade]; 
     break; 
} 
} 

-(void)configureCell:(GiftEventTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{ 
switch (indexPath.section) { 
    case WISHLIST_SECTION: 
    { 
     GiftEvent *giftEv=(GiftEvent *)[fetchedResultsControllerwish objectAtIndexPath:indexPath]; 
     cell.gift=giftEv; 

    }; 
     break; 
    case PURCHASED_SECTION: 
    { 
     GiftEvent *giftEv=(GiftEvent *)[fetchedResultsControllerPurchased objectAtIndexPath:indexPath]; 

     //if i don't use indexpath.row in the second section i get an out of bounds error 
     //GiftEvent *giftEv=(GiftEvent *)[[fetchedResultsControllerPurchased fetchedObjects]objectAtIndex: indexPath.row]; 
     cell.gift=giftEv; 

    }; 
     break; 




    default: 
     break; 
} 

} 

// Override to support editing the table view. 
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
if (editingStyle == UITableViewCellEditingStyleDelete) 
{ 
    switch (indexPath.section) { 
     case WISHLIST_SECTION: 
     { 
      // Delete the managed object for the given index path 

      [self.managedObjectContext deleteObject:[fetchedResultsControllerwish objectAtIndexPath:indexPath]]; 

      // Save the context. 
      NSError *error; 
      if (![self.managedObjectContext save:&error]) { 
       /* 
       Replace this implementation with code to handle the error appropriately. 

       abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
       */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 
      [self.tableView reloadData]; 

      }; 
      break; 
     case PURCHASED_SECTION: 
     { 
      // Delete the managed object for the given index path 

      [self.managedObjectContext deleteObject:[fetchedResultsControllerPurchased objectAtIndexPath:indexPath]]; 

      // Save the context. 
      NSError *error; 
      if (![self.managedObjectContext save:&error]) { 
       /* 
       Replace this implementation with code to handle the error appropriately. 

       abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
       */ 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 

     }; 
      break; 

     default: 
      break; 
    } 
} 
} 

Trả lời

1

:) xin lỗi các bạn đó là một lỗi noob .. lỗi đã xảy ra vì indexPath.section trả về phần trong tableView nhưng tôi không có phần nào trong fetchedResultsController (luôn là chỉ mục 0). EDIT: thực sự có một ..

NSIndexPath *indexPathTemp = [NSIndexPath indexPathForRow:indexPath.row inSection:0]; 

Không chắc chắn nếu đó là cách tốt nhất nhưng giải quyết được vấn đề.
Thks!
Ricardo Castro

1

Sử dụng nhiều là cách tiếp cận sai. Giải pháp đúng là sử dụng thông số sectionNameKeyPath cho số NSFetchedResultController để nhóm các kết quả thành nhiều phần, trong trường hợp của bạn, nó sẽ là thuộc tính boolean đã mua trên sản phẩm. Và bạn cũng nên làm cho bộ mô tả sắp xếp thứ nhất này theo thứ tự tăng dần vì bạn muốn mua chưa được mua ở trên.Sử dụng phương thức ủy nhiệm bảng tiêu đề tiêu đề để trả về chuỗi "Danh sách yêu thích" và "Đã mua" cho từng chỉ mục phần.

Nếu bạn nghĩ rằng bạn có thể có danh sách thứ 3 trong tương lai, thì tốt hơn bạn nên sử dụng thuộc tính trạng thái số và mã trong một enum cho từng trạng thái (hoặc danh sách) sản phẩm có thể ở đó. điều này được thực hiện hơn là phân loại trên một bool.