场景是我有多个想要调用通讯簿的视图。为了不在每个视图中复制委托的代码,我将代码放在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的地址。无论如何,这是我对它的看法......
答案 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)
编辑好的,整个第一个答案已被抛弃。这有一些警告,在黑暗中仍然有点像一个镜头,但我认为这将更接近有用。虽然有些想法可以继续下去。
您很可能不需要单独的课程来充当您的ABPeoplePickerNavigationControllerDelegate
。很可能,它应该是同一个类,底部有你的代码(调用presentModalViewController:animated:
。因为我不知道那是什么控制器,所以我只打电话给它MyViewController
您希望该视图控制器成为委托的原因是,在您的委托方法中,您需要能够关闭具有地址簿的模态视图控制器。
您肯定不希望您的计划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
答案 2 :(得分:0)
最后,我无法按照预期执行上述任何建议。我不得不缩短时间并继续前进,所以我在每个视图中复制了代码。我将在另一次重新审视,因为我确信它可以基于更加基于对象的方式完成,而不是我结束它。