3

My app needs to associate instances of a custom class with contact records in the iPhone's AddressBook. Everything's all well and good when I present the ABPeoplePickerNavigationController and allow the user to pick an existing contact. Problem is there's no obvious way to allow a user to easily ADD a contact record if the one they're looking for doesn't already exist in their AddressBook.

How are people getting from ABPeoplePickerNavigationController to ABNewPersonViewController in a way that's easy & intuitive for the user?

Meltemi
  • 37,979
  • 50
  • 195
  • 293

3 Answers3

6

You can create a UIBarButton and add it to the UINavigationBar of the ABPeoplePickerNavigationController like so.

    peoplePicker.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addPerson:)];

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

The issue that i came up against was that the ABPeoplePickerNavigationController has a cancel button placed in the rightBarButtonItem slot and I had to update the navigation bar on the

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{

I have documented the entire process on my blog with a worked example that should allow you to create a contacts style application similar to that on the iPhone. Hope this helps.

Scott Sherwood
  • 3,108
  • 25
  • 30
3

I found Scott Sherwood's approach along with the demo he posted on his site to be very helpful. As one of the commenters on his blog mentioned though, there is a problem with the Cancel button in Edit mode.

I just proposed a fix to Scott's demo, along with a different approach for the Person View Controller at: http://finalize.com/2013/05/12/using-and-customizing-the-address-book-ui/

My suggestion for the Person View Controller was to put it up manually in the protocol method peoplePickerNavigationController:shouldContinueAfterSelectingPerson: for the ABPeoplePickerNavigationControllerDelegate.

// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{

    ABPersonViewController *view = [[ABPersonViewController alloc] init];

    view.personViewDelegate = self;
    view.displayedPerson = person; // Assume person is already defined.
    view.allowsEditing = YES;
    view.allowsActions = YES;

    [peoplePicker pushViewController:view animated:YES];

    return NO;
}

The only issue here is that the People Picker table view of names is not refreshed automatically after an edit. This can be fixed with the use of an Address Book callback. I show how this can be done in the GitHub project I posted at:

https://github.com/scottcarter/AddressBookPeoplePicker.git

Scott Carter
  • 1,254
  • 9
  • 16
1

it appears that it is not possible to add a new contact directly from the ABPeoplePickerNavigationController. Therefore, when the user clicks an add button, I am presenting an UIActionSheet with two buttons:

- (void) addContact{

    contactMenu = [[UIActionSheet alloc] 
                           initWithTitle: nil 
                           delegate:self
                           cancelButtonTitle:@"Cancel"
                           destructiveButtonTitle: nil
                           otherButtonTitles:@"Select a contact", @"Add a new contact", NULL];

    [contactMenu showInView:self.view];

}

Here is the associated delegate method:

    - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{



        if(buttonIndex == 0){
            // select an existing contact   
            ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];
            peoplePicker.peoplePickerDelegate = self;
            [self presentModalViewController:peoplePicker animated:YES];

        }

        if(buttonIndex == 1){

            // add a new contact
            ABNewPersonViewController *newPersonViewController = [[ABNewPersonViewController alloc] init];
            newPersonViewController.newPersonViewDelegate = self;

            UINavigationController *personNavController = [[UINavigationController alloc] initWithRootViewController:newPersonViewController];
            [self presentModalViewController:personNavController animated:YES];

            [personNavController release];
            [newPersonViewController release];

        }

            if(buttonIndex == 2){
        // cancel the operation
        [actionSheet dismissWithClickedButtonIndex:2 animated:YES];
    }


}
Massimo Cafaro
  • 25,429
  • 15
  • 79
  • 93