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

时间:2009-08-24 07:34:50

标签: iphone ios addressbook

更新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'元素告诉程序显示电话号码。这会产生一些奇怪的行为;当我选择一个没有分配电话号码的联系人时,联系人会在后台显示“无电话号码”(正如您所期望的那样),但是当选择一个有电话号码的联系人时,我得到的只是一个空白的联系页面(没有“无电话号码”文本)。

这是我用于创建 PersonViewController 类的 ABPeoplePickerNavigationController委托类中的方法,该类实现 ABPersonViewController接口: < / p>

- (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;
}

这是我的 PersonViewController.h 头文件:

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

@interface PersonViewController : UIViewController <ABPersonViewControllerDelegate> 
{

}

- (void) displayContactInfo: (ABRecordRef)person;

@end

最后,这是我的 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

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


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

[self setView:personController.view];

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

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

1 个答案:

答案 0 :(得分: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;
}

这是我的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

最后,这是委托的实现(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

希望这最终会对某人有所帮助。 AddressBook UI框架对我来说有点棘手(虽然我是iPhone开发的新手,所以我还在学习iPhone程序组织的许多细微差别)。