简体   繁体   中英

ios 8 : ABPeoplePickerNavigationController dismiss on implementing people picker delegate methods

This is strange behavior noticed while accessing contact details from address book in ios 8. My scenario is simple

  1. Show contacts table
  2. select a row that will invoke didSelectPerson method
  3. in didSelectPerson method
  4. push SecondViewController

     - (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker didSelectPerson:(ABRecordRef)person; { SecondViewController *detailVC = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [detailVC.view setBackgroundColor: [UIColor redColor]]; // [peoplePicker.navigationController pushViewController:detailVC animated:YES]; [peoplePicker pushViewController:detailVC animated:YES]; } 

but what happens is ABPeoplePickerNavigationController dismiss. Please enlighten me on this.

I don't know the philosophy thing what happens under the hood of the " didSelectPerson " method, me was facing the same problem today. I found a simple solution to overcome this issue, i override the " -(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion " method of the " ABPeoplePickerNavigationController ". Then implement it like somewhat following

    bool dismissedEnabled;
   -(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
   {
     if (dismissedEnabled) {
       [super dismissViewControllerAnimated:flag completion:completion];
     }
   }

then inside the " didSelectPerson " i have done the following

   viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:[NSBundle mainBundle]];

    dismissedEnabled = false;
    [self presentViewController:viewController animated:YES completion:nil];

this works for me, hope you guys overcome it too :)

It automatically dismisses if you select a contact with a single email address for example. If a contact has more than one email, you must specify a predicate that will force the ABPeoplePickerNavigationController to push a ABPersonViewController on the stack.

if ([picker respondsToSelector:@selector(setPredicateForSelectionOfPerson:)])
    {
        // The people picker will select a person that has exactly one email address and call peoplePickerNavigationController:didSelectPerson:,
        // otherwise the people picker will present an ABPersonViewController for the user to pick one of the email addresses.
        picker.predicateForSelectionOfPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count = 1"];
    }

I believe the default behavior in iOS 8 is that the ABPeoplePickerNavigationController is automatically dismissed when didSelectPerson is called.

The reason that the SecondViewController is not displayed (I'm inferring that this is the problem symptom) is because you are trying to push the SecondViewController while the ABPeoplePickerNavigationController is being dismissed. This overlapping animation is a problem that the iOS core view management/animation system tries to avoid.

You may get a warning in the console when this happens.

@Ratul's solution works because it circumvents this default behavior.

In my scenario, my code sleeps a second before presenting a UIAlertController from within didSelectPerson . This is a hack that depends on the ABPeoplePickerNavigationController dismissal animation taking less than a second. For me, if this alert is not displayed, nobody would even notice this was a problem.

If you want something more robust, you may want to override viewDidAppear to handle this special case (using a flag in your presenting view controller). But this gets a bit clumsy as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM