When using the ABPeoplePickerNavigationController or any of the view controllers in the Address Book framework I kept getting a cancel button placed on the right hand side of the navigation bar which I could not remove. This was obviously an extremely annoying problem and creating the same interaction that you get on the iPhone contacts app was not possible.

The add button on the main people screen and the edit button on the persons detailed pane were always over written by the cancel button. After spending several hours googling and trying the simple,

[self setAllowsCancel:NO];

However, this method is not available in iOS5 so I came up with the following solution. First I created a new blank solution to try out my idea, adding both the AddressBook.framework and the AdressBookUI.framework to the project and the following to the pre-compiled header.

#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>

I then created a simple button on my storyboard and hooked it up to an IBAction and set the current class as the UINavigationControllerDelegate and implement the relevant method


-(IBAction)addPerson:(id)sender{
    ABNewPersonViewController *view = [[ABNewPersonViewController alloc] init];
    view.newPersonViewDelegate = self;
    UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:view];
    [self.picker presentModalViewController:nc animated:YES];
}

-(IBAction)cancel:(id)sender{
    [self dismissModalViewControllerAnimated:YES];
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    
    //set up the ABPeoplePicker controls here to get rid of he forced cacnel button on the right hand side but you also then have to 
    // the other views it pcuhes on to ensure they have to correct buttons shown at the correct time.
    
    if([navigationController isKindOfClass:[ABPeoplePickerNavigationController class]]){
        navigationController.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addPerson:)];
        
        navigationController.topViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];  
    }
}

To dismiss the ABNewPersonViewController you need to implement the ABNewPersonViewControllerDelegate and ensure that you dismiss the ABNewPersonViewController rather than simply calling dismiss on self (this one caught me out for a few minutes)

#pragma mark - ABNewPersonViewControllerDelegate
 
// Called when the user selects Save or Cancel. If the new person was saved, person will be
// a valid person that was saved into the Address Book. Otherwise, person will be NULL.
// It is up to the delegate to dismiss the view controller.
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonView didCompleteWithNewPerson:(ABRecordRef)person{
    [newPersonView dismissModalViewControllerAnimated:YES];    
}

If you run the application now you will see the buttons laid out correct and by clicking on the cancel and add button the correct actions are executed. The final issue to resolve occurs when you tap on a contact. When the detail view is pushed onto the screen you will see that the add button remains as the top right navigation item when in fact you want an edit button that toggles back and forth to done. First you have to augment the willShowViewController to detect when the detail view is pushed on and remove the left navigation item to leave room for the back navigation button that is automatically replace the add button with an edit button.

 
-(IBAction)editPerson:(id)sender{
    [self.picker.topViewController setEditing:YES animated:YES];
 
    self.picker.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done:)];
}
 
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
 
   if([navigationController isKindOfClass:[ABPeoplePickerNavigationController class]] 
       && [viewController isKindOfClass:[ABPersonViewController class]]){
        navigationController.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editPerson:)];
 
        navigationController.topViewController.navigationItem.leftBarButtonItem = nil; 
    }
    else if([navigationController isKindOfClass:[ABPeoplePickerNavigationController class]]){
        navigationController.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addPerson:)];
 
        navigationController.topViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];  
    }
}

Please give the complete AddressBookDemo a try all feedback is more than welcome.