无法在 iOS 8 上选择联系人

Posted

技术标签:

【中文标题】无法在 iOS 8 上选择联系人【英文标题】:Cannot select contact on iOS 8 【发布时间】:2014-09-24 19:09:47 【问题描述】:

我有一个ABPeoplePickerNavigationController 的子类来处理在我的应用中选择联系电话号码。在 ios 7 及更低版本上一切正常。

但是,在 iOS 8 上,我的ABPeoplePickerNavigationControllerDelegate 在选择电话号码时不会被击中。相反,它只是拨打那个电话号码。

我注意到我在 iOS 7 中用于处理联系人选择的方法 (peoplePickerNavigationController:shouldContinueAfterSelectingPerson:property:identifier:) 在 iOS 8 中已弃用。此方法已被 peoplePickerNavigationController:didSelectPerson:property:identifier: 取代。

我知道我的委托已设置,因为我成功收到了 peoplePickerNavigationControllerDidCancel: 方法回调。

有其他人遇到过这个问题吗?

这是我的ABPeoplePickerNavigationController 子类的代码 sn-p:

- (void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 

    [self peoplePickerNavigationController:peoplePicker shouldContinueAfterSelectingPerson:person property:property identifier:identifier];


- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier 

    ...do stuff...

    return NO;


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

    return YES;


- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker 

    [self dismissViewControllerAnimated:self.shouldAnimateDismiss completion:NULL];

【问题讨论】:

你指定了什么predicateForSelectionOfProperty 您是否使用 Xcode 6 构建并且您的项目是否具有 iOS 8 的 Base SDK? @Rob 什么都没有。没有设置它总是有效的。 @rmaddy 是的,是的。 好的。在 iOS 8 中,predicateForSelectionOfProperty 也会影响这种行为,所以我不得不问。无论如何,您是否确认(使用断点或日志语句)这些委托方法被调用了?例如。正确指定了peoplePickerDelegate(注意,不是delegate)? 【参考方案1】:

您在哪里指定peoplePickerDelegate

在 iOS 8 中,如果您在 viewDidLoad 中指定 peoplePickerDelegate,您将遇到您描述的奇怪行为(取消委托有效,didSelect...shouldContinue... 无效)。如果您在init 之后(或期间)立即指定peoplePickerDelegate,则可以正常工作。

这似乎是 iOS 8 的“功能”。我会提交错误报告。

【讨论】:

那是我的问题。谢谢!!这确实是一个非常奇怪的变化。 我的问题是我指定了picker.delegate = self 而不是picker.peoplePickerDelegate = self @Rob 您好,先生,我在我的项目中做得很好,我在按钮单击方法上指定了 peoplePickerDelegate,但现在取消方法工作正常,但 (BOOL)peoplepickernavigationcontroller 没有被调用。【参考方案2】:

以上两种委托方法在 iOS 8.0 中已弃用,请使用最后两种方法来获得您想要的结果

这是苹果开发者指南链接,为您提供更多信息

ABPeoplePickerNavigationControllerDelegate

【讨论】:

【参考方案3】:

当我在 IOS8 中选择联系人时,什么都不会发生。

我发现除了

if ([picker respondsToSelector:@selector(setPredicateForSelectionOfPerson:)]) 
    
         picker.predicateForSelectionOfPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count = 1"];
    

我也需要

if ([picker respondsToSelector:@selector(setPredicateForEnablingPerson:)])
    
        picker.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
    

来源https://developer.apple.com/library/prerelease/ios/samplecode/PeoplePicker/Listings/PeoplePicker_AAPL_8or7_EmailPickerViewController_m.html

【讨论】:

【参考方案4】:

如果你只想得到人的名字,你可以这样做:

-(IBAction)btnGetContact
    ABPeoplePickerNavigationController *personPicker = [ABPeoplePickerNavigationController new];
    personPicker.peoplePickerDelegate = self;
    [self presentViewController:personPicker animated:YES completion:nil];


-(void)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
        NSString *firstName;
    NSString *middleName;
    NSString *lastName;
    UIImage *retrievedImage;

    // get the first name
    firstName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);

    //get the middle name
    middleName = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonMiddleNameProperty);

    // get the last name
    lastName = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

    // get personPicture
    if (person != nil && ABPersonHasImageData(person))
    
        retrievedImage = [UIImage imageWithData:(__bridge_transfer NSData*)ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail)];
    
    else
    
        retrievedImage = nil;
    

但是,如果您要查看人员的详细信息以获取人员的号码,则应使用 BOOL 而不是 void 代替 peoplePickerNavigationController 并传递 YES,如下所示:

-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
    return YES;




 -(void) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker didSelectPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
        ABMutableMultiValueRef phoneno  = ABRecordCopyValue(person, kABPersonPhoneProperty);

CFStringRef phone = ABMultiValueCopyValueAtIndex(phoneno, identifier);

        _mPhone.text = (__bridge NSString *)phone;

        [self dismissViewControllerAnimated:NO completion:^()];
    

另外不要忘记将AddressBook.frameworkAddressBookUI.framework 导入您的项目和ABPeoplePickerNavigationControllerDelegate

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

到你的头文件。

【讨论】:

以上是关于无法在 iOS 8 上选择联系人的主要内容,如果未能解决你的问题,请参考以下文章

UINavigationController 内的 TUITabBarController 问题

在 iOS 上选择退出 UISceneDelegate/SwiftUI

在其中一个联接上选择具有最大值的记录

无法在奥利奥上选择文件

在真实设备上选择 PDF 时 iOS 文档选择器崩溃

无法在 Instruments 上选择跟踪活动分配