Несколько NsfetchedResultsController в UItableView - PullRequest
7 голосов
/ 03 сентября 2010

Мне трудно реализовать 2 nsfetchedresultsController в tableView. Я хотел получить fetchedresultsController в каждом разделе таблицы (2 раздела), что-то вроде этого:

* 1007 лист пожеланий *

  • продукт
  • product2

Куплено

  • product3

Я знаю, что для этого примера мне не понадобится 2 nsfetchedResultsController, но мне это понадобится позже ..

когда я удаляю продукт из одного nsfetchedResultsController, он передается другому, и я получаю эту ошибку:

Неверное обновление: недопустимое количество строк в разделе 0. Количество строки, содержащиеся в существующем разделе после обновления (0) должны быть равно числу строк, содержащихся в этом разделе перед обновить (0), плюс или минус количество строк, вставленных или удаленных из этот раздел (1 вставлено, 0 удалено). with userInfo (null) "

Я думаю, это происходит потому, что, когда первый fetchedRController обнаруживает изменение, он обновляет tableView перед вызовом второго, верно? я должен использовать NSMutableArrays и обновить tableView вручную?

код:

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

Ответы [ 4 ]

4 голосов
/ 03 сентября 2010

Проверьте этот другой вопрос о переполнении стека:


Основные данные: UITableView с несколькими NSFetchedResultControllers

Основные данные: UITableView с несколькими NSFetchedResultControllers

2 голосов
/ 18 октября 2017

Использование нескольких является неправильным подходом. Правильное решение - использовать параметр sectionNameKeyPath для NSFetchedResultController, чтобы сгруппировать результаты в несколько разделов, в вашем случае это будет приобретенное логическое свойство продукта. И вы также должны сделать это первым дескриптором сортировки в порядке возрастания, так как вы хотите приобрести непокупанное выше. Используйте метод делегата таблицы заголовков заголовков, чтобы вернуть строки «Список пожеланий» и «Куплено» для каждого индекса раздела.

Если вы думаете, что в будущем у вас может появиться третий список, то вам лучше использовать числовое свойство статуса и в коде перечисление для каждого из состояний (или списков), в котором может находиться продукт. Обычно это так делается вместо сортировки по бул.

1 голос
/ 30 декабря 2014

Я только что создал модуль для решения этой проблемы.https://github.com/imton/GMCoreDataMultipleSectionsTableVC

Вы можете проверить это и сказать, что вы думаете, обратная связь приветствуется!

G

1 голос
/ 17 сентября 2010

:) извините, ребята, это была ошибка noob .. ошибка происходила потому, что indexPath.section вернул раздел в tableView, но у меня не было разделов в fetchedResultsController (всегда index 0). РЕДАКТИРОВАТЬ: на самом деле есть один ..

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

Не уверен, что это лучший способ, но решил проблему.
Thks!
Рикардо Кастро

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...