numberOfRowsInSection: method for core data and multiple sections

前端 未结 1 1797
时光说笑
时光说笑 2020-12-10 20:46

I am trying to show a table view with 2 sections. The first section will always have 1 row and the second section will have as many rows as data points. I am using Core Da

相关标签:
1条回答
  • 2020-12-10 20:57

    The reason is that the fetched results controller (FRC) has only one section (section #0), which you want to be displayed in the second section (section #1) of the table view.

    This is possible, but you have to map between FRC section numbers and table view section numbers, e.g.

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

    The same mapping is necessary in cellForRowAtIndexPath.

    In the FRC delegate methods didChangeObject, didChangeSection you have to add 1 to the section number before calling the table view methods (e.g. insertRowsAtIndexPaths).


    ADDED: configureCell should look like this:

    - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.section == 0) {
            cell.textLabel.text = entityOne.name;  //entityOne object passed from previous VC
        } else {
            NSIndexPath *frcIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(indexPath.section - 1)];
            entityTwo = [self.fetchedResultsController objectAtIndexPath:frcIndexPath];
            cell.textLabel.text = entityTwo.name;
        }
    }
    

    and didChangeObject like this:

    - (void)controller:(NSFetchedResultsController *)controller
       didChangeObject:(id)anObject
           atIndexPath:(NSIndexPath *)indexPath
         forChangeType:(NSFetchedResultsChangeType)type
          newIndexPath:(NSIndexPath *)newIndexPath
    {
        UITableView *tableView = self.tableView;
        NSIndexPath *tvIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(indexPath.section + 1)];
        NSIndexPath *tvNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:(newIndexPath.section + 1)];
    
        switch(type) {
            case NSFetchedResultsChangeInsert:
                [tableView insertRowsAtIndexPaths:@[tvNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
    
            case NSFetchedResultsChangeDelete:
                [tableView deleteRowsAtIndexPaths:@[tvIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
    
            case NSFetchedResultsChangeUpdate:
                [self configureCell:[tableView cellForRowAtIndexPath:tvIndexPath] atIndexPath:tvIndexPath];
                break;
    
            case NSFetchedResultsChangeMove:
                [tableView deleteRowsAtIndexPaths:@[tvIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                [tableView insertRowsAtIndexPaths:@[tvNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
    

    You probably get the idea:

    • When going from FRC index path to table view index path, add one to the section.
    • When going from table view index path to FRC index path, subtract one from the section.
    0 讨论(0)
提交回复
热议问题