19

2010 年 9 月 2 日更新: このコードは、iOS 4 の更新時点で機能しなくなりました。内部アサーションで失敗します。「QuickContacts」と呼ばれる iPhone SDK Reference Library で利用できる優れた Address Book API の例が現在あります。

サンプルコードはこちらから入手できます。この問題を解決するのに役立ちます: http://developer.apple.com/iphone/library/samplecode/QuickContacts/Introduction/Intro.html


ユーザーが ABPeoplePickerNavigationControllerから連絡先を選択できるようにする機能をアプリに追加しようとしています。これにより、選択した連絡先に対応する ABPersonViewController表示されます。その時点で、ユーザーが連絡先の電話番号をクリックして、アプリがカスタム動作で応答できるようにしたいと考えています。

ABPeoplePickerNavigationControllerは正常に動作していますが、ABPersonViewControllerを表示する際に問題が発生しています。ABPersonViewControllerを画面上でアニメーション化することはできますが、連絡先の写真、名前、および会社名しか表示されません。連絡先の他のフィールドは表示されません。

ABPersonViewControllerの「displayedProperties 」要素を使用して、プログラムに電話番号を表示するように指示しています。これにより、奇妙な動作が発生します。電話番号が割り当てられていない連絡先を選択すると、背景に「電話番号なし」と書かれた連絡先が表示されますが (ご想像のとおり)、電話番号が割り当てられている連絡先を選択すると、空白の連絡先ページ (「電話番号なし」テキストなし)。

ABPeoplePickerNavigationController デリゲートクラスのメソッドを次に示します。これは、 ABPersonViewController インターフェイスを実装するPersonViewControllerクラスを作成するために使用しています。

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

最後に、選択した連絡先を表示するためのABPersonViewControllerを作成するPersonViewController.mを次に示します。

#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 スタックに正しく追加されません。

PersonViewController だけでなく、ABPersonViewController をスタックに追加する方法を知っている人はいますか?

4

1 に答える 1

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プログラム編成の微妙な違いをまだ学んでいます)。

于 2009-08-31T07:17:21.377 に答える