Search code examples
iosxcodexcode4ios5

How do I tell the address book picker which fields to fill out?


I am VERY new with iOS development. So, please make your response as exact and basic as possible.

I have a form with two (at the moment - there could be more) fields that will have a button next to each that allows the user to select a contact from the iPad address book and fill the relevant field with the first and last name from the address book.

Basic Form Mockup

The example code I have got me to the point that I can fill in the Contact Name. However, I would like to be able to click on the 'Browse Contacts' button next to Referred By, and have it use the same functions to fill in the referred by name. I see that the getContactName function has the sender parameter. So, I could easily tell which of the two buttons (or others later) were clicked.

But, when I pick from the address book, how do I know which button was clicked in the peoplePickerNavigationController or fillContactName functions?

- (IBAction)getContactName:(id)sender {

    ABPeoplePickerNavigationController *picker =
    [[ABPeoplePickerNavigationController alloc] init];
    picker.peoplePickerDelegate = self;

    [self presentModalViewController:picker animated:YES];
}


- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
        [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    [self fillContactName:person];

    [self dismissModalViewControllerAnimated:YES];

    return NO;
}

- (BOOL)peoplePickerNavigationController:
(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}


- (void)fillContactName:(ABRecordRef)person
{
    NSString* firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person,
                                                                    kABPersonFirstNameProperty);

    NSString *test = [firstName stringByAppendingString:@" "];

    NSString* lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person,
                                                                         kABPersonLastNameProperty);

    NSString *fullName = [test stringByAppendingString:lastName];

    self.contactName.text = fullName;

}

Solution

  • Here's one way you could do it.

    First, assign your "Browse Contacts" button unique int values for their tag property when they are created (or in the storyboard, if you are using storyboards) so that you can tell them apart in your getContactName: method. I would suggest setting tag=0 for the first button and tag=1 for the second button.

    Then add a new property to your ViewController class that will store a pointer to the target text field after the button is clicked. (Be sure to @synthesize in your .m file)

    @property (nonatomic, strong) UITextField *targetTextField;
    

    In getContactName:, inspect the sender object and use its tag value to set the pointer appropriately. (Note that the sender will be the UIButton object that the user clicked).

    - (IBAction)getContactName:(id)sender {
    
        ...
    
        switch(sender.tag) {
            case 0:
                self.targetTextField = self.contactName;
                break;
            case 1:
                self.targetTextField = self.referredBy;
                break;
            default:
                self.targetTextField = nil;
        }           
    
        [self presentModalViewController:picker animated:YES];
    }
    

    Then in fillContactName:, set the text value to the text field at the targetTextField which you have previously set.

    - (void)fillContactName:(ABRecordRef)person
    {
        NSString* firstName = (__bridge_transfer NSString*)ABRecordCopyValue(person,kABPersonFirstNameProperty);
        NSString* lastName = (__bridge_transfer NSString*)ABRecordCopyValue(person,kABPersonLastNameProperty);
    
        self.targetTextField.text = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
    }
    

    Note that I have used the NSString class method stringWithFormat: to make your fillContactName code more concise. This is a commonly used method in a case like this.