почему peoplePickerDelegate не может правильно указать адрес делегата? - PullRequest
0 голосов
/ 02 декабря 2011

Сценарий состоит в том, что у меня есть несколько представлений, которые хотят вызвать адресную книгу. Чтобы не дублировать код делегата в каждом представлении, я поместил код в заголовок и файл .m делегата приложения, а использовал «@interface AddressBookDelegate» и «@implementation AddressBookDelegate» в нижней части 2 соответствующих приложений. Делегатский вечер -

@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 для подключения к коду делегата адреса, если он физически не находится в том же файле, что и само представление? Thx.

ДОБАВЛЕНО ПРИМЕЧАНИЕ: когда я использую отладчик и останавливаюсь на линии

abPicker.peoplePickerDelegate = addressBookDelegate;

в коде представления я вижу, что адрес addressBookDelegate указан как адрес MyprogAppDelegate, а не AddressBookDelegate, как я мог бы ожидать. Это заставляет меня думать, что смещение кода делегата адресной книги отключено в файле делегата приложения.

Если код делегата отмены AddressBookDelegate, скажем, 1000 байтов в AddressBookDelegate, мое приложение фактически «вводит» код 1000 байтов в MyprogAppDelegate, и поэтому происходит сбой. Так или иначе, я не настраиваю адресацию AddressBookDelegate правильно. В любом случае, это мое мнение ...

Ответы [ 3 ]

1 голос
/ 02 декабря 2011

Ваш код предполагает, что ваш 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{

}
0 голосов
/ 11 января 2012

В конце концов я не смог заставить ни одно из вышеперечисленных предложений работать так, как надеялись.Мне пришлось сократить время и двигаться дальше, поэтому я дублировал код в каждом представлении.Я вернусь к этому в другой раз, так как уверен, что это можно сделать более объектно-ориентированным способом, чем я это сделал.

0 голосов
/ 02 декабря 2011

РЕДАКТИРОВАТЬ Хорошо, весь первый ответ был отброшен. Это, с некоторым предупреждением, все еще немного выстрел в темноте, но я думаю, что это будет ближе к полезным. Однако некоторые идеи остаются в силе.

  1. Вам очень вероятно не нужен отдельный класс, чтобы действовать как ваш ABPeoplePickerNavigationControllerDelegate. По всей вероятности, это должен быть тот же класс, в котором внизу находится ваш код (который вызывает presentModalViewController:animated:. Поскольку я не знаю, что это был за контроллер, я просто для справки назову его MyViewController. причина, по которой вы хотите, чтобы этот контроллер представления был делегатом, заключается в том, что в ваших методах делегата необходимо иметь возможность отклонить модальный контроллер представления, имеющий адресную книгу.

  2. Вы определенно не хотите, чтобы UIApplicationDelegate вашей программы было ABPeoplePickerNavigationControllerDelegate. Как вы сами сказали, 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
...