I have a tableview that is successfully incorporating an NSFetchedResultsController. However, I need the topmost cell in my tableview to read, “Add new object” and have UITableViewCellEditingStyleInsert instead of the default UITableViewCellEditingStyleDelete.
The FetchResultsController wants to check the managedObjectContext for objects–both to determine number of rows and to populate the table cells. The only way I can think to get around this is to create a dummy object, but I feel like there ought to be a more elegant solution.
UPDATE:
For those who might be curious as to what solution I ended up with, I decided to have my insert cell at the bottom, not the top. Here is the relevant code:
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
//self.clearsSelectionOnViewWillAppear = NO;
self.editing = YES;
self.tableView.allowsSelectionDuringEditing = YES;
self.tableView.delegate = self;
RubricAppDelegate *appDelegate = (RubricAppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"myClass" inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"classID" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
fetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil cacheName:nil];
NSError *error;
[fetchedResultsController performFetch:&error];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSLog(@"Number of sections = %d", [[fetchedResultsController sections] count]);
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
id <NSFetchedResultsSectionInfo> myClass = [[fetchedResultsController sections] objectAtIndex:section];
NSLog(@"Number of classes = %d", [myClass numberOfObjects]);
return ([[fetchedResultsController fetchedObjects] count] + 1);
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSLog(@"FRC count + 1 = %d", ([[fetchedResultsController fetchedObjects] count] + 1));
if (indexPath.row == ([[fetchedResultsController fetchedObjects] count])) {
cell.textLabel.text = @"Add New Class";
}
else {
myClass *theClass = [fetchedResultsController objectAtIndexPath:indexPath];
NSLog(@"Class name is: %@", theClass.classTitle);
cell.textLabel.text = theClass.classTitle;
}
return cell;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [[fetchedResultsController fetchedObjects] count]) {
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}
The result (with some junk data):

Now my only issue is getting the delete functions to work properly. You can follow my post on that issue here
Normally the add row is at the bottom.
You can accomplish this by changing the
-tableView:numberOfRowsInSection:and the-tableView:cellForRowAtIndexPath:methods to adjust the cell count and adjust for it. So your-tableView:numberOfRowsInSection:would return N+1 and your-tableView:cellForRowAtIndexPath:would get object at N-1 unless N == 0 then it would return your “Add new object” cell.There is no need to mess with the underlying Core Data elements as this is strictly a UI issue.
Update
Yes it is the count of actual objects.
You do want your
-tableView:cellForRowAtIndexPath:to return a cell for your “Add new object” otherwise what is the point? You just want it to return a different type of cell.All you are doing in this solution is adding a cell that is not part of the
NSFetchedResultsControllerand then compensating for it when you are retrieving an actual object from theNSFetchedResultsControllerand when the user selects a cell.