I am trying to make ABPeoplePickerNavigationController work like Contact App and find it is way too complicated. I am not sure if this is because I have done it wrong or it is just the way it is.
The first task is to get rid of Cancel button at right bar button. The following code开发者_如何学运维 does NOT work!
picker.navigationItem.rightBarButtonItem = nil;
I was confused for a while then found out that it is because the Cancel rightBarButtonItem belongs to the subview ABPeoplePickerNavigationController contains, e.g. ABPersonViewController, but NOT ABPeoplePickerNavigationController itself! And this is the reason. It is easy to verify that, just print out picker.navigationItem.rightBarButtonItem, it is nil all the time.
So I implement ABPeoplePickerNavigationController.delegate (not peoplePickerDelegate). But it took quite some tricks in implementing it and that comes my questions.
So code first:
#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;
}
}
}
The first weird thing here is that when ABPeoplePickerNavigationController only contains 1 or 2 subviews, case 1 and case 2 here, the viewController is ABAccountsAndGroupsViewController, ABMembersViewController respectively.
ABAccountsAndGroupsViewController and ABMembersViewController are not the public API for AddressBookUI, so I can't to access them directly (I got them by print out their names). That is why I check viewControllers's count instead. So my first question is why doesn't Apple them public API ?
The second question is about ABPersonViewController (Case 3). If it is ABNewPersonViewController, its navigationItem can correctly show the "Cancel" and "Done" UIBarButtonItem. I do not need to do anything there.
But if it is ABPersonViewController, the "Cancel" UIBarButtonItem still show as rightBarButtonItem instead of Edit Button (even I have set allowsEditing to YES ). So I have to set it manually. But why ?? Is there is better way to do it?
And is there any better way than the code I wrote here to make ABPeoplePickerNavigationController work like Contact App?
Thanks!
After upgraded to iOS 5 I find the code needs some modification. When ABPeoplePickerNavigationController shows ABAccountsAndGroupsViewController (case 1), these is now a refresh bar button on the left. I am not sure if that is used to sync contacts from exchange server or what action it will trigger ?
But if I substitute the default button with my own refresh button, my action won't be called! And I find that it only happens to ABAccountsAndGroupsViewController, other cases still work!
So to make my codes work in iOS 5, I have to implemented delegate method didShowViewController NOT willShowViewController
精彩评论