为什么peoplePickerDelegate没有得到委托的地址吧?

时间:2011-12-02 09:29:39

标签: ios xcode addressbook abpeoplepickerview

场景是我有多个想要调用通讯簿的视图。为了不在每个视图中复制委托的代码,我将代码放在App Delegate的头文件和.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以连接到Address Delegate代码? THX。

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

abPicker.peoplePickerDelegate = addressBookDelegate;

在视图代码中,我看到addressBookDelegate的地址被声明为MyprogAppDelegate的地址,而不是我可能预期的AddressBookDelegate。这让我觉得在App Delegate文件中,地址簿代理代码的位移是关闭的。

如果AddressBookDelegate取消委托代码在AddressBookDelegate中说1000字节,我的应用程序实际上是将代码“输入”MyprogAppDelegate中的1000字节,因此崩溃了。所以我不知道我没有正确设置AddressBookDelegate的地址。无论如何,这是我对它的看法......

3 个答案:

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

}

答案 1 :(得分:0)

编辑好的,整个第一个答案已被抛弃。这有一些警告,在黑暗中仍然有点像一个镜头,但我认为这将更接近有用。虽然有些想法可以继续下去。

  1. 很可能不需要单独的课程来充当您的ABPeoplePickerNavigationControllerDelegate。很可能,它应该是同一个类,底部有你的代码(调用presentModalViewController:animated:。因为我不知道那是什么控制器,所以我只打电话给它MyViewController您希望该视图控制器成为委托的原因是,在您的委托方法中,您需要能够关闭具有地址簿的模态视图控制器。

  2. 肯定不希望您的计划UIApplicationDelegate成为ABPeoplePickerNavigationControllerDelegate。正如您自己所说,peoplePickerDelegate必须是UIViewController

  3. 所以,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
    

答案 2 :(得分:0)

最后,我无法按照预期执行上述任何建议。我不得不缩短时间并继续前进,所以我在每个视图中复制了代码。我将在另一次重新审视,因为我确信它可以基于更加基于对象的方式完成,而不是我结束它。