0

シナリオは、アドレス帳を呼び出したいビューが複数あるというものです。各ビューでデリゲートのコードを複製しないように、アプリ デリゲートのヘッダーと .m ファイルにコードを配置しましたが、2 つのそれぞれのアプリの下部にある「@interface AddressBookDelegate」と「@implementation AddressBookDelegate」を使用します。デリゲート・フィエ-

@interface AddressBookDelegate : UIViewController <ABPeoplePickerNavigationControllerDelegate> {
AddressBookDelegate *addressBookDelegate;   
}
@property (nonatomic, retain) AddressBookDelegate *addressBookDelegate;
@end

@implementation AddressBookDelegate
@synthesize addressBookDelegate;

- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker 
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{   
    [super dismissModalViewControllerAnimated:YES];

    ...get stuff from the Address Book...   

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person 
                            property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

次に、私の見解では、次のコードがあります。

addressBookDelegate = (AddressBookDelegate *) [[UIApplication sharedApplication] delegate];

ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc]init];    
abPicker.peoplePickerDelegate = self.addressBookDelegate;
[self presentModalViewController:abPicker animated:YES];
[abPicker release];

アドレス帳はすべてのビューで正常に表示されます。しかし、アドレス帳の [キャンセル] ボタンなど、デリゲートを呼び出すユーザー アクションを実行すると、クラッシュします。

-[MyprogAppDelegate peoplePickerNavigationControllerDidCancel:]: 認識されないセレクターがインスタンスに送信されました

警告なしでクリーンにコンパイルされます。

ビュー自体と物理的に同じファイルにない場合、アドレス デリゲート コードに接続するために peoplePickerDelegate を接続するにはどうすればよいですか? どうも。

追記: デバッガーを使用して途中で停止した場合

abPicker.peoplePickerDelegate = addressBookDelegate;

ビューのコードでは、addressBookDelegate のアドレスが、予想していた AddressBookDelegate ではなく、MyprogAppDelegate のアドレスであると記述されていることがわかります。これは、App Delegate ファイル内で、アドレス帳のデリゲート コードへの置換がオフになっていると思わせます。

AddressBookDelegate Cancel Delegate コードが AddressBookDelegate に 1000 バイトあるとすれば、私のアプリは実際には 1000 バイトのコードを MyprogAppDelegate に「入力」しているため、クラッシュします。そのため、どういうわけか、AddressBookDelegate のアドレス指定を正しく設定していません。とにかくそれは私の考えです...

4

3 に答える 3

1

コードは、appdelegate(MyprogAppDelegate)がメソッドを実装していることを前提としていますpeoplePickerNavigationControllerDidCancel

したがって、MyprogAppDelegateのコードは次のようになります。

@implementation MyprogAppDelegate
@synthesize ...;

#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    


    return YES;
}

- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker{

}
于 2011-12-02T09:39:24.910 に答える
0

編集さて、最初の答え全体が捨てられました。これは、いくつかの警告がありますが、まだ暗闇の中でのショットですが、より役立つものになると思います. ただし、いくつかのアイデアは引き継がれます。

  1. として機能する別のクラスはおそらく必要ありませんABPeoplePickerNavigationControllerDelegate。おそらく、あなたのコードが一番下にあるのと同じクラスであるはずです(それは を呼び出しますpresentModalViewController:animated:。それがどのコントローラーだったのかわからないのでMyViewController、参照用に呼び出すだけです。そのビューコントローラーが必要な理由デリゲートになるのは、デリゲート メソッドで、アドレス帳を持つモーダル ビュー コントローラーを閉じることができる必要があるためです。

  2. あなたのプログラムUIApplicationDelegateABPeoplePickerNavigationControllerDelegate. あなたが自分で言ったように、 でpeoplePickerDelegateなければなりませんUIViewController

だから、にMyViewController。まず、インターフェース:

/* MyViewController.h */

@interface MyViewController : UIViewController<ABPeoplePickerNavigationControllerDelegate>
...
@end

コントローラーは UIViewController の子孫 (テーブル ビュー コントローラーなど) を継承する場合があります。これは変更しないでください。変更する必要があるのはABPeoplePickerNavigationControllerDelegate、実装されたプロトコルのリストに を追加することだけです。

次に、機能を実装します。

/* MyViewController.m */

@implementation MyViewController

...
- (void) whateverMethodIsDisplayingTheAddressBook
{
    ABPeoplePickerNavigationController *abPicker = [[ABPeoplePickerNavigationController alloc]init];    
    abPicker.peoplePickerDelegate = self; // This view controller is the delegate
    [self presentModalViewController:abPicker animated:YES];
    [abPicker release];
}

...

- (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker 
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
{   
    [super dismissModalViewControllerAnimated:YES];

    ...get stuff from the Address Book...   

    return NO;
}

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person
                                property:(ABPropertyID)property
                              identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

@end
于 2011-12-02T19:51:48.143 に答える
0

結局、上記の提案のいずれも期待どおりに機能させることができませんでした。時間を短縮して次に進む必要があったため、各ビューでコードを複製しました。私はこれを別の機会に再訪します.

于 2012-01-11T06:59:39.353 に答える