1

In my app I have a viewcontroller which is the delegate of NSFetchedResultsController and the delegate and datasource of a UITableView.

When an add button in the navigation controller is pressed, the next view is pushed correctly and I can correctly add a new Person entity.

My issue is that when the add button is pressed, a blank row is added to the tableView as the new view is pushed, and is still there after the new entity record is correctly created

This is the target action for the add button:

- (void)addPerson:(id)sender
{
    AddPersonViewController *addPersonController = [[AddPersonViewController alloc] initWithNibName:@"AddPersonViewController" bundle:nil];

    [addPersonController setPerson:[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext]];

    [self.navigationController pushViewController:addPersonController animated:YES];
}

The code that creates the blank row (from the apple docs for the NSFetchedResultsControllerDelegate) is here:

- (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 configureCell:[tableView cellForRowAtIndexPath:indexPath]
                    atIndexPath:indexPath];
            break;

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

Any ideas how to stop this blank row being created?

Leon
  • 715
  • 1
  • 8
  • 22

1 Answers1

1

Calling

[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext]

in addPerson creates a new Person object and adds it to the managed object context. If the fetched results controller of the table view is configured to get all Person objects, this will result in a new (blank) table row for this new object.

I don't know how your AddPersonViewController works. If it modifies the object given via setPerson, then the table row should be updated. If it creates a new Person object, then the first (blank) entry will remain.

You should probably delay the creating of the new Person object until the AddPersonViewController has all data to actually create and populate the object. You could do this either by moving the insertNewObjectForEntityForName: call to the AddPersonViewController, or by using a delegate method in your table view controller that is called from the AddPersonViewController.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Thanks for the reply. Which in your mind is the best solution; to use a delegate method, or move the call into the `AddPersonViewController`? – Leon Oct 14 '12 at 12:27
  • @Leon: I would use a delegate, but both solutions are OK (in my opinion). – Martin R Oct 14 '12 at 12:53
  • How would I call the method from the `AddPersonViewController`? I'm very new to iOS programming. – Leon Oct 14 '12 at 16:08
  • @Leon: There are a lot of questions/answers on stackoverflow about the delegate pattern, for example here: http://stackoverflow.com/questions/1045803/how-does-a-delegate-work-in-objective-c. There is also documentation from Apple. - But you can just as well move the insert call to the AddPersonViewController. - Please feel free to ask more questions if necessary. – Martin R Oct 14 '12 at 16:19
  • Got it working, moved the insert call to my save method. Thanks for your help! – Leon Oct 15 '12 at 19:48