0

我试图让 ABPeoplePickerNavigationController 像 Contact App 一样工作,但发现它太复杂了。我不确定这是因为我做错了还是事情就是这样。

第一个任务是去掉右栏按钮上的取消按钮。以下代码不起作用!

picker.navigationItem.rightBarButtonItem = nil; 

我迷茫了一会儿才发现这是因为取消rightBarButtonItem属于ABPeoplePickerNavigationController包含的子视图,例如ABPersonViewController,而不是ABPeoplePickerNavigationController本身!这就是原因。很容易验证,只要打印出picker.navigationItem.rightBarButtonItem,它一直都是nil。

所以我实现了 ABPeoplePickerNavigationController.delegate(不是 peoplePickerDelegate)。但是实现它需要一些技巧,这就是我的问题。

所以先编码:

#pragma mark UINavigationControllerDelegate methods
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    switch ([navigationController.viewControllers count]) {
        case 1:
            viewController.navigationItem.rightBarButtonItem = nil;
            break;
        case 2: {
            UIBarButtonItem *addButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addButtonClicked)];
            [viewController.navigationItem setRightBarButtonItem:addButtonItem animated:NO];
            [addButtonItem release];
            break;
        }
        case 3: {
            UIBarButtonItem *editButtonItem;
            if ([viewController isKindOfClass:[ABPersonViewController class]]) {    

                editButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editButtonClicked:)];
                self.personView  = (ABPersonViewController*) viewController;
                self.personView.allowsEditing = YES;
                [viewController.navigationItem setRightBarButtonItem:editButtonItem animated:NO];
                [editButtonItem release];

             } else {
                //ABPersonNewViewController
                //No need to add codes here
            }            
            break;
        }           
        default: {          
            UIBarButtonItem *cancelButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(addButtonClicked)];
            [viewController.navigationItem setRightBarButtonItem:cancelButtonItem animated:NO];
            [cancelButtonItem release];
            break;
        }
    }   
}

这里第一个奇怪的是,当 ABPeoplePickerNavigationController 只包含 1 或 2 个子视图时,这里的 case 1 和 case 2,viewController 分别是 ABAccountsAndGroupsViewController,ABMembersViewController。

ABAccountsAndGroupsViewControllerABMembersViewController不是 AddressBookUI 的公共 API,所以我不能直接访问它们(我通过打印它们的名字得到它们)。这就是为什么我改为检查 viewControllers 的计数。所以我的第一个问题是为什么 Apple 他们不公开 API ?

第二个问题是关于 ABPersonViewController(案例 3)。如果是ABNewPersonViewController,它的navigationItem可以正确显示“Cancel”和“Done”的UIBarButtonItem。我不需要在那里做任何事情。

但如果它是 ABPersonViewController,“取消”UIBarButtonItem 仍显示为 rightBarButtonItem 而不是编辑按钮(即使我已将 allowEditing 设置为 YES )。所以我必须手动设置它。但为什么 ??有更好的方法吗?

还有比我在这里写的代码更好的方法来使 ABPeoplePickerNavigationController 像 Contact App 一样工作吗?

谢谢!

4

1 回答 1

0

升级到 iOS 5 后,我发现代码需要一些修改。当 ABPeoplePickerNavigationController 显示 ABAccountsAndGroupsViewController(案例 1)时,这些现在是左侧的刷新栏按钮。我不确定这是否用于从交换服务器同步联系人或它将触发什么操作?

但是,如果我用我自己的刷新按钮替换默认按钮,我的操作将不会被调用!而且我发现它只发生在 ABAccountsAndGroupsViewController 上,其他情况仍然有效!

所以为了让我的代码在 iOS 5 中工作,我必须实现委托方法didShowViewController NOT willShowViewController

于 2011-11-10T03:31:06.743 回答