Editing the Attractions List, Part Two

In my last post, I described how I added a toolbar to the top of the AttractionsViewController, and enabled editing mode. This makes adding, deleting, and reordering rows an easy task.

I’ll tackle deletion first, which is easy, albeit more of a magic incantation than the others. When the red deletion circles are pressed, the message commitEditingStyle:forRowAtIndexPath is called on the view controller.

The first unusual thing you’ll notice is the slightly unconventional if statement. Putting the constant before the == is a habit of mine from my C days. It takes some getting used to, but if you accidentally type

*constant* = *variable*

this is a syntax error caught by the compiler, but

*variable* = *constant*

is an excruciatingly difficult logic error that will cost you hours of lost productivity.

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (UITableViewCellEditingStyleDelete == editingStyle) {
        Attraction *a = [attractions objectAtIndex:[indexPath row]];
        [[AttractionStore defaultStore] removeAttraction:a];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    }
}

Once you get past the if statement, the function has basically two parts

  • Remove the Attraction from the AttractionStore
  • Remove the corresponding row from the TableView

Move is even simpler, just move the corresponding Attraction in the AttractionStore. The row has already been moved in the TableView,by the user.

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    [[AttractionStore defaultStore] moveAttractionAtIndex:[sourceIndexPath row] toIndex: [destinationIndexPath row]];
}

Create is probably the most complex of the three, but even this isn’t hard. I create a new attraction, then send that to a new instance of AttractionDetailViewController. The only complicating factor is wrapping the detail controller in a UINavigationController to make it easier to pop back when finished.

- (IBAction)addNewAttraction:(id)sender
{
    Attraction *attraction = [[AttractionStore defaultStore] createAttraction];

    AttractionDetailViewController *detailViewController = [[AttractionDetailViewController alloc] initWithAttraction:attraction forNewItem:YES];

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
    [detailViewController release];

    [self presentModalViewController:navController animated:YES];
    [navController release];     
}

No rocket science here. Editing in the detail view “just works.”. The only thing missing is a cancel button, which should be fairly easy to add. My next task…

I’m going to cut back in detail in future posts, focusing on what I’ve learned or found interesting. I’ve found myself explaining a lot of basic code snippets, which is time-consuming and probably not very interesting if you know iOS development. If you don’t know iOS development, it probably isn’t enough. (just go read The Big Nerd Ranch already).