0

这种情况是我有多个视图想要调用地址簿。为了不在每个视图中重复委托的代码,我在 App Delegate 的标头和 .m 文件中找到了代码,但在两个相应 App 的底部使用了“@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 与视图本身不在同一个文件中时,如何连接它以连接到 Address Delegate 代码?谢谢。

添加注意:当我使用调试器并停止在线时

abPicker.peoplePickerDelegate = addressBookDelegate;

在视图代码中,我看到 addressBookDelegate 的地址被声明为 MyprogAppDelegate 的地址,而不是我预期的 AddressBookDelegate 的地址。这让我觉得地址簿委托代码的置换在 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. 绝对不希望您的程序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
于 2011-12-02T19:51:48.143 回答
0

最后,我无法使上述任何建议按预期执行。我不得不缩短时间并继续前进,所以我在每个视图中复制了代码。我将再次讨论这个问题,因为我确信它可以以一种比我结束它更基于对象的方式来完成。

于 2012-01-11T06:59:39.353 回答