This is how I do it. One notable point: CoreData does not store booleans, so any property labeled "boolean" is actually of type NSNumber
. You've got to remember to convert back and forth when dealing with CoreData and boolean values.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *selectedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([[selectedObject valueForKey:@"isDone"] boolValue]) {
[selectedObject setValue:[NSNumber numberWithBool:NO] forKey:@"isDone"];
} else {
[selectedObject setValue:[NSNumber numberWithBool:YES] forKey:@"isDone"];
}
}
I have my UITableViewController
set as the the delegate for the NSFetchedResultsController
, so the changes I made to the managed objects in the query ^^^ will cause the following two methods to be run.
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *defaultCellIdentifier = @"Item";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:defaultCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:defaultCellIdentifier] autorelease];
}
NSManagedObject *item = [[self fetchedResultsController] objectAtIndexPath:indexPath];
cell.textLabel.text = [item valueForKey:@"name"];
if ([[item valueForKey:@"checks"] boolValue]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Here's how everything ties together
- User clicks on a row
- tableView:didSelectRow... method changes the "isDone" property of the appropriate managed object.
- the fetched results controller notices that a managed object has changed and calls the
controllerDidChangeContent
method on its delegate.
- My
controllerDidChangeContent
method just reloads all the data in the table view
- When the tableView is reloaded, my tableView:cellForRow... method checks the "isDone" property of the managed item to see if the cell should have a checkmark or not.
And just so you don't get confused, I initially used a generic NSMangagedObject
to store row state, which is why the first method I posted says, [selectedObject valueForKey:@"isDone"]
. Later I switched to a subclassed managed object named JKItem
, which is why the second set of methods is able to use item.isDone
without generating a compiler warning.