Question

I have an iOS Core Data application with some table view issues. In the application there is a Master View Controller that contains a table view and a separate Creator View Controller that creates the Core Data managed objects with the populated data.

The current goal of the app is to load text from the Core Data object into a table view cell (in the MVC table view), and when the cell is tapped, display a new cell underneath (drop down) that shows additional information.

I'm running into problems in -[tableView:cellForRowAtIndexPath:] where I try to access a specific Core Data object using [self.fetchedResultsController objectAtIndexPath:indexPath]; Due to the extra child cells attempting to be instantiated, I cannot call the correct object at the correct index path. If I had enough parent cells, I would receive an incorrect object in return. If I didn't have enough parent cells, I would get a SIGABRT error due to calling an object out of index bounds.

I have an array that holds all of the index paths of the subcells, so that's implemented for row count in the -[tableView:numberOfRowsInSection:]

If anyone has any advice, or if I need to provide clarification, please let me know. I don't want to do a messy code dump, so I'm showing what I think are the applicable parts of the MasterViewController.hfile. (If I have too much, please also make me aware)

@interface MasterViewController ()
@property (nonatomic, strong) NSMutableArray *subIndexPaths;
@end

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Trinomial" inManagedObjectContext:[self managedObjectContext]];
  [fetchRequest setEntity:entity];
  NSError *error = nil;
  NSInteger count = [_managedObjectContext countForFetchRequest:fetchRequest error:&error];

  if ([self.subIndexPaths count] == 0 || !self.subIndexPaths) {
      return count;
}

  return (count + [self.subIndexPaths count]);

}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  //Child cell created & returned here
  {
  ...
  }

  //Create a parent cell & setup/return
  UITableViewCell *parentCell = [tableView dequeueReusableCellWithIdentifier:kParentCell];
  Trinomial *currentTri = [self.fetchedResultsController objectAtIndexPath:indexPath];
  parentCell.textLabel.text = [currentTri retrieveTrinomial];
  return parentCell;

}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  if ([[[tableView cellForRowAtIndexPath:indexPath] reuseIdentifier] isEqualToString:kParentCell]) {
    if ([self.subIndexPaths containsObject:[NSIndexPath indexPathForRow:(indexPath.row + 1) inSection:indexPath.section]]) {
        //When there is already a child cell present

        [self.subIndexPaths removeObject:newIndexPath];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:newIndexPath, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView reloadData];

    } else {
      //When there isn't a child cell present

      [self.subIndexPaths addObject:newIndexPath];
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
      [self.tableView reloadData];

    }
Was it helpful?

Solution

Ok, what you're trying to do currently is going to get very messy very quickly if you continue.

Instead, I'd change your approach so that any parent cell which doesn't have a child is displayed as the current cell type, and any parent with a child is displayed as a different cell type - which includes the content for both the parent and the child.

In this way, your indexes aren't all messed up. You section and row counts become simple. (incidentally, you shouldn't run a new fetch to get the count, get it from the FRC instead).

The only mildly complex bit is determining the row height and which cell type to use...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top