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

        DefaultContactSelectViewController *view = [[self storyboard] instantiateViewControllerWithIdentifier:@"DefaultContactView"];
        view.recordID  = recordID;
        view.phones = phones;
        view.emails = emails;
        view.first_name = first_name;
        view.last_name = last_name;
        view.delegate = self;

        [peoplePicker pushViewController:view animated:YES];
    return NO;
}

In the above code example, I'm pushing a custom contact view controller after selecting a contact. The problem is if the contact is selected from the search result, and then the user clicks back to get back to the contact picker, the search result will be cleared.

this problem does not happen if the above code return YES, but then it will push the default contact view which is not what I want.

Thanks in advance if you know how I can fix this issue.

Monolo
  • 18,205
  • 17
  • 69
  • 103
Ricky Gu
  • 585
  • 1
  • 4
  • 13

2 Answers2

2

You should probably write a custom PeoplePickerViewController since you'll never have enough control over Apple's default controller.

Anyway, as for your current problem, here's what you need to do:

Declare three new properties (use appropriate declarations based on if you are using ARC or not - I'm assuming no ARC)

@property (nonatomic, assign) ABPeoplePickerNavigationController *peoplePicker;
@property (nonatomic, assign) UIViewController *peoplePickerRootViewController;
@property (nonatomic, copy) NSString *currentSearchString;

Now, when you display people picker, add these lines:

// save people picker when displaying
self.peoplePicker = [[[ABPeoplePickerNavigationController alloc] init] autorelease];

// save it's top view controller
self.peoplePickerRootViewController = self.peoplePicker.topViewController;

// need to see when view controller is shown/hidden - viewWillAppear:/viewWillDisappear: won't work so don't bother with it.
self.peoplePicker.delegate = self;

Now, we'll save search string just before pushing person view:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    self.currentSearchString = nil;
    if ([self.peoplePickerRootViewController.searchDisplayController isActive])
    {
        self.currentSearchString = self.peoplePickerRootViewController.searchDisplayController.searchBar.text;
    }
    // other stuff... 

Obviously, implement UINavigationControllerDelegate in this class. When the root view comes back into view, we will force display search results view. Here's the implementation for navigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (navigationController == self.peoplePicker)
    {
        if (viewController == self.peoplePickerRootViewController)
        {
            if (self.currentSearchString)
            {
                [self.peoplePickerRootViewController.searchDisplayController setActive: YES];
                self.peoplePickerRootViewController.searchDisplayController.searchBar.text = self.currentSearchString;
                [self.peoplePickerRootViewController.searchDisplayController.searchBar becomeFirstResponder];
            }
            self.currentSearchString = nil;
        }
    }
}

Don't forget to release currentSearchString in dealloc if not using ARC.

Small caveat: There is a slight flicker when you select a person when ABPeoplePickerNavigationController is trying to hide the search results view.

maroux
  • 3,764
  • 3
  • 23
  • 32
  • This worked, thanks. I also saved the scroll position of the search result and added: [self.peoplePickerRootViewController.searchDisplayController.searchResultsTableView setContentOffset:scrollPosition animated:NO]; tonavigationController "willShowViewController", but setting the scroll only seem to work in "didShowViewController", which is not ideal. Any idea why it won't set the scroll in willShowViewController? – Ricky Gu May 07 '13 at 02:41
0

Ok i had a similar issue. I presume you are using ARC?

If so i saved and passed the whole to ABRecordRef to my other view and then had to retain the person object using:

CFRetain( m_MyContact object );

Dont forget to then use CFRelease() on the object when you are finished.

Dev2rights
  • 3,469
  • 3
  • 25
  • 42