如何正确使用ABPersonViewController与ABPeoplePickerNavigationController查看联系信息?

Jas*_*cek 19 iphone addressbook ios

更新9/2/10:此代码不再适用于iOS 4更新 - 它失败并带有内部断言.现在,iPhone SDK参考库中提供了一个名为"QuickContacts"的优秀通讯簿API示例.

示例代码可在此处获得; 它将帮助您解决此问题:http: //developer.apple.com/iphone/library/samplecode/QuickContacts/Introduction/Intro.html


我正在尝试向我的应用添加一项功能,允许用户从ABPeoplePickerNavigationController中选择一个联系人,然后显示与他们选择的联系人对应的ABPersonViewController.此时,我希望用户能够点击联系人的电话号码并让我的应用程序响应自定义行为.

我已经让ABPeoplePickerNavigationController工作正常了,但是我遇到了显示ABPersonViewController的问题.我可以让ABPersonViewController在屏幕上动画很好,但它只显示联系人的照片,名称和公司名称.没有显示联系人的其他字段.

我正在使用ABPersonViewController中的'displayedProperties'元素告诉程序显示电话号码.这会产生一些奇怪的行为; 当我选择一个没有分配电话号码的联系人时,联系人会在后台显示"无电话号码"(正如您所期望的那样),但是当选择一个有电话号码的联系人时,我得到的只是一个空白的联系页面(没有"无电话号码"文本).

下面是我的方法的ABPeoplePickerNavigationController委托类,我使用创建我PersonViewController类,它实现了ABPersonViewController接口:

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

    BOOL returnState = NO;

    PersonViewController *personView = [[PersonViewController alloc] init];
    [personView displayContactInfo:person];

    [peoplePicker pushViewController:personView animated:YES];

    [personView release];

    return returnState;
}
Run Code Online (Sandbox Code Playgroud)

这是我的PersonViewController.h头文件:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AddressBookUI/AddressBookUI.h>

@interface PersonViewController : UIViewController <ABPersonViewControllerDelegate> 
{

}

- (void) displayContactInfo: (ABRecordRef)person;

@end
Run Code Online (Sandbox Code Playgroud)

最后,这是我的PersonViewController.m,它创建了ABPersonViewController来查看所选的联系人:

#import "PersonViewController.h"

@implementation PersonViewController

- (void) displayContactInfo: (ABRecordRef)person
{
    ABPersonViewController *personController = [[ABPersonViewController alloc] init];

    personController.personViewDelegate = self;
    personController.allowsEditing = NO;
    personController.displayedPerson = person;
    personController.addressBook = ABAddressBookCreate();

    personController.displayedProperties = [NSArray arrayWithObjects:
            [NSNumber numberWithInt:kABPersonPhoneProperty], 
            nil];

    [self setView:personController.view];

    [[self navigationController] pushViewController:personController animated:YES];
    [personController release];
}

- (BOOL) personViewController:(ABPersonViewController*)personView shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
    return YES;
}


@end
Run Code Online (Sandbox Code Playgroud)

有没有人知道为什么我看到这个空白的联系人屏幕而不是一个可点击的电话号码字段?


好吧,我想我越来越接近找到问题了.我很确定这是上面displayContactInfo调用的这一部分:

[self setView:personController.view];
Run Code Online (Sandbox Code Playgroud)

当我省略这一行时,当我点击一个联系人时,我看到的只是一个空白屏幕.ABPeoplePickerNavigationController将PersonViewController推送到NavigationController堆栈.然后PersonViewController实例化一个ABPersonViewController对象,但无论出于何种原因,ABPersonViewController永远不会被正确添加到NavigationController堆栈中.

有谁知道如何将ABPersonViewController添加到堆栈,而不仅仅是PersonViewController?

Jas*_*cek 9

只是对自己遇到这个问题的任何人提出挑战:我能够通过在其委托的viewDidLoad()方法中实例化ABPersonViewController来产生正确的行为,如下所示:

和以前一样,这是我的ABPeoplePickerNavigationController委托的方法:

- (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    BOOL returnState = NO;

    PersonViewController *personView = [[PersonViewController alloc] init];

    [peoplePicker pushViewController:personView animated:YES];
    [personView displayContactInfo:person];

    [personView release];

    return returnState;
}
Run Code Online (Sandbox Code Playgroud)

这是我的PersonViewController.h(ABPersonViewController委托)头文件:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AddressBookUI/AddressBookUI.h>

@interface PersonViewController : UIViewController <ABPersonViewControllerDelegate> 
{
    ABPersonViewController *personController;
}

- (void) displayContactInfo: (ABRecordRef)person;

@end
Run Code Online (Sandbox Code Playgroud)

最后,这是委托的实现(PersonViewController.m):

#import "PersonViewController.h"

@implementation PersonViewController

- (void) viewDidLoad
{
}

- (void) viewDidUnload
{
    [personController release];
}

- (void) displayContactInfo: (ABRecordRef)person
{
    personController = [[ABPersonViewController alloc] init];
    [personController setDisplayedPerson:person];
    [personController setPersonViewDelegate:self];
    [personController setAllowsEditing:NO];
    personController.addressBook = ABAddressBookCreate();   

    personController.displayedProperties = [NSArray arrayWithObjects:
        [NSNumber numberWithInt:kABPersonPhoneProperty], 
        nil];

    [self setView:personController.view];
}

- (BOOL) personViewController:(ABPersonViewController*)personView shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
    // This is where you pass the selected contact property elsewhere in your program
    [[self navigationController] dismissModalViewControllerAnimated:YES];
    return NO;
}

@end
Run Code Online (Sandbox Code Playgroud)

希望这最终会对某人有所帮助.该通讯录的UI框架是有点棘手,让我绕到我的头(虽然我是新iPhone的发展,所以我还在学习很多iPhone程序组织的细微差别).