Пример Core Data Books Добавление пользовательской ячейки

Я основал свое приложение на примере проекта Core Data Books, предоставленного Apple, и сделал каждую ячейку пользовательской ячейкой, которая отображает определенные данные, работает волшебным образом.

Однако теперь я пытаюсь добавить вторую пользовательскую ячейку. Это отдельная ячейка, которая всегда будет первой ячейкой в ​​таблице, после чего все результаты, полученные из основных данных, идут ниже нее.

Я пробовал так:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{    
    if (indexPath.row == 0) 
    {
        static NSString *CellIdentifier = @"statsCell";

        GuestStatsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        {
            cell = [[GuestStatsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

        //Configure the cell.
        [self configureStatsCell:cell];

        return cell;
    }
    else
    {
        static NSString *CellIdentifier = @"guestCell";

        customGuestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        {
            cell = [[customGuestCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }

        // Configure the cell.
        [self configureGuestCell:cell atIndexPath:indexPath];

        return cell;
    }
}

Наряду с некоторыми другими изменениями, чтобы попытаться заставить все работать. Несколько проблем.

Во-первых, представление загружается нормально, я получаю свою пользовательскую ячейку с индексом 0, а затем мои основные ячейки данных загружаются ниже этого. Первая проблема: самая первая основная ячейка данных не видна, поскольку она скрыта за моей пользовательской ячейкой, но если я нажму на нее, я получу подробное представление для этой основной записи данных. Поэтому мне нужно решить, как я могу остановить это за этой пользовательской ячейкой.

Я пытался исправить это, например, кажется логичным, что этот кусок:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

Таким образом, это устанавливает только достаточное количество ячеек для основных записей данных и не учитывает эту дополнительную пользовательскую ячейку. Итак, я пробую что-то простое:

return [sectionInfo numberOfObjects] + 1;

Затем это приводит к этой строке, из-за которой я получаю сбой и индекс за пределами ошибки:

GuestInfo *guest = [fetchedResultsController objectAtIndexPath:indexPath];

Эта строка взята из метода configureCell, который настраивает основные ячейки записи данных. Так что я в замешательстве, что делать.

Следующая проблема: когда я редактирую атрибут любой основной записи данных в подробном представлении, возвращаясь к табличному представлению, моя пользовательская ячейка не показывает никаких изменений. Он отображает статистику, связанную с основной информацией о данных. Обновляются только другие ячейки.

Любая помощь будет очень признательна, и если вам нужно увидеть больше кода или вам нужно больше объяснений, дайте мне знать.

РЕДАКТИРОВАТЬ:

Больше кода по запросу, чтобы помочь мне. Это код NSFetchedController.

- (NSFetchedResultsController *)fetchedResultsController 
{

    if (fetchedResultsController != nil) 
    {
        return fetchedResultsController;
    }

    // Create and configure a fetch request with the Book entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"GuestInfo" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    // Create the sort descriptors array.
    NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastName" ascending:YES];
    NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:lastNameDescriptor, firstNameDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    // Create and initialize the fetch results controller.
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"displayOrder" cacheName:@"Root"];

    self.fetchedResultsController = aFetchedResultsController;
    fetchedResultsController.delegate = self;

    // Memory management.
    //No releasing with ARC!

    return fetchedResultsController;
}    


/**
 Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
 */

- (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)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

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

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

        case NSFetchedResultsChangeUpdate:
            [self configureGuestCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            [self.tableView reloadData];
            break;

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


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


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

person Josh Kahane    schedule 15.01.2012    source источник
comment
Вы включаете ARC? Если нет, ячейка, возвращаемая -tableView:cellForRowAtIndexPath:, должна быть автоматически освобождена.   -  person AechoLiu    schedule 16.01.2012
comment
Вы использовали NSFetchedResultController. Итак, не могли бы вы опубликовать коды о настройке fetchedResultController? И коды о [fetchedResultsController PerformFetch:...]. Кстати, после изменения атрибутов управляемого объекта вы вызываете [tableView reloadData] для обновления табличного представления?   -  person AechoLiu    schedule 16.01.2012
comment
Да, я использую ARC. Вызов [self.tableView reloadData] помогает решить проблему перезагрузки данных в моей единственной пользовательской ячейке. Однако все еще нужно разобраться с этим нечетным перекрытием ячеек, я опубликую запрошенный вами код.   -  person Josh Kahane    schedule 16.01.2012
comment
Возможно, проще сказать. Я хочу, чтобы моя пользовательская ячейка имела индекс 0 в таблице. Затем все основные данные получили результаты, которые последуют за этим. В настоящее время результаты основных данных начинаются с индекса 0, как я могу это настроить?   -  person Josh Kahane    schedule 16.01.2012
comment
Нужна ли эта пользовательская ячейка каждому разделу? Если да, то -tableView:numberOfRowsInSection: должен возвращать `1+[sectionInfo numberOfObjects]. И вам нужно вручную настроить путь индекса при возврате ячейки с помощью fetechedResultController.   -  person AechoLiu    schedule 17.01.2012
comment
Это помогло, спасибо. Правильная настройка indexPath при необходимости остановила ошибку индекса за пределами границ, которую я получал, увеличивая количество строк в разделе.   -  person Josh Kahane    schedule 17.01.2012


Ответы (1)


Я реализую ту же функцию и использую смещение с решением indexPath @Toro, которое работает просто отлично. Не знаю есть ли способ лучше или нет вот моя поправка для интересующихся.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects] + 1;
}

Добавьте одну дополнительную строку для моей пользовательской ячейки, мой полученный результат не имеет раздела, поэтому я отлично работаю.

- (NSIndexPath *)adjustedIndexPath:(NSIndexPath *)indexPath
{
    NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
    return newPath;
}

частный метод для настройки indexpath для получения правильного объекта из NsFetchedResultController.

Вот метод, который я применяю adjustedIndexPath:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
person sarunw    schedule 25.01.2012