New Item works fine, editing item no longer does


#1

So I’m a bit confused here. I kept waiting for the solution in the book, since there isn’t any other post about it, but it never came that I noticed.

As soon as we changed to presenting the DetailViewController modally (pg. 268), the behavior of the app changed. We got the exception with the “Cancel” and “Done” buttons because of the reasons spelled out in the chapter…I understand so far. We then add the save: and cancel: methods in DetailViewController to give specific instructions for when those buttons are pushed within the FormStyle when adding a new item…all good. I build and run the app and everything seems to work fine. I create a new item, edit the properties in the form, click done or cancel and everything works as it should.

However, I notice that if I click on an item from the tableView to modify it, the cancel and done buttons no longer do anything. I’m thinking to myself that there must be more code coming, because if you “edit” an existing item, and push the cancel button, that the item is now going to be deleted because of the cancel: code I just wrote. But nothing was ever mentioned about this problem. Instead, nothing happens. No exception thrown…nothing. Clicking Done does nothing as well. I’m stuck with the DetailView onscreen.

Therefore, I’m guessing that I made some mistake somewhere. I would include code here, but I’m honestly not sure which code to include. I’ve been trying to track this down myself, but I’m just not sure where to look any further. All my code seems to look like what’s in the book. I understand there may be a typo, but when adding/editing a new item for the first time, everything works perfectly…

In looking at the code that creates the buttons:

- (id)initForNewItem:(BOOL)isNew
{
   self = [super initWithNibName:@"DetailViewController" bundle:nil];
   
   if (self) {
      UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                                target:self
                                                                                action:@selector(save:)];
      [[self navigationItem] setRightBarButtonItem];
      
      UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                                  target:self
                                                                                  action:@selector(cancel:)];
      [[self navigationItem] setLeftBarButtonItem:cancelItem];
   }
   return self;
}

… It looks like the buttons were set to call some canned save: and cancel: methods, since I just created the save and cancel overriding methods. Hmm…that’s makes me wonder if there is some [super cancel] and [super save] method of some kind…I’m guessing no…but similar?

Anyway, nobody else has brought this up, so I’m not sure what to do or look at.

Here are my cancel and save methods from DetailViewController.m:

- (void)cancel:(id)sender
{
   // If the user cancelled, then remove the BNRItem from the store
   [[BNRItemStore sharedStore] removeItem:item];
   
   [[self presentingViewController] dismissViewControllerAnimated:YES completion:dismissBlock];
}

- (void)save:(id)sender
{
   [[self presentingViewController] dismissViewControllerAnimated:YES completion:dismissBlock];
}

Here is my tableView:didSelectRowAtIndexPath method from ItemsViewController.m that creates the instance of DetailViewController for editing:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:NO];
   
   NSArray *items = [[BNRItemStore sharedStore] allItems];
   BNRItem *selectedItem = [items objectAtIndex:[indexPath row]];
   
   // Give detail view controller a pointer to the item object in row
   [detailViewController setItem:selectedItem];
   
   // Push it onto the top of the navigation controller's stack
   [[self navigationController] pushViewController:detailViewController animated:YES];
}

Thanks for giving me some direction. Sorry if I used any incorrect terminology. I am new to this. I read the Objective-C BNR book, and now this one. I haven’t been out on my own yet, so I’m still developing my vocabulary.

Thanks again,
Phil


#2

Ok, figured it out.

In my code to create the Done and Cancel buttons, which I forgot didn’t show up previously, I forgot to check to see if the New(+) button initialized the instance of the class. Therefore,

My first draft of code looked like this:

- (id)initForNewItem:(BOOL)isNew
{
   self = [super initWithNibName:@"DetailViewController" bundle:nil];
   
   if (self) {
      UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                                target:self
                                                                                action:@selector(save:)];
      [[self navigationItem] setRightBarButtonItem];
      
      UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                                  target:self
                                                                                  action:@selector(cancel:)];
      [[self navigationItem] setLeftBarButtonItem:cancelItem];
   }
   return self;
}

And my working code now looks like:

self = [super initWithNibName:@"DetailViewController" bundle:nil];
   
   if (self) {
      if (isNew) {      // ****This is what I forgot previously
         UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                                   target:self
                                                                                   action:@selector(save:)];
         [[self navigationItem] setRightBarButtonItem];
         
         UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                                     target:self
                                                                                     action:@selector(cancel:)];
         [[self navigationItem] setLeftBarButtonItem:cancelItem];
      }
   }
   return self;

Feel good about finding that one. Took longer than appears by time stamps…