iphoneiosabpersonviewcontroller

How can I override the "Done" button in ABNewPersonViewController


I have a class that subclasses ABNewPersonViewController. As I understand, when the Done button in the navigation bar is clicked, the delegate method

- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person 

gets called. But before entering the delegate method, the changes will be saved to address book.

What I need is, as soon as the save button gets pressed. I need to load a UIView with 2 buttons asking the user,

  1. whether he wants the changes and
  2. whether he should abort the changes made,

But this should be done before the changes are reflected in the address book. And only on the click of the first button in the UIView, that the changes should be saved in the address book.

On the click of the 2nd button, the view should disappear and I should return to the view controller class from where the UIView is loaded.

My question is, how will I load the view on save button click, before the changes are reflected in the address book

I have created a custom save button

UIBarButtonItem *okBtn =  self.navigationItem.rightBarButtonItem;
UIBarButtonItem *saveBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:okBtn.target action:okBtn.action];
self.navigationItem.rightBarButtonItem =saveBtn;
[saveBtn release];

On the save button action, the control goes to the delegate method

 - (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person`  .

I want the control go to my custom method, where I can load my UIView before the edits are saved in the address book.

Edit: When I load the ABNewPersonViewController

 ABPersonViewController *displayVcardViewController = (ABPersonViewController*)[self.navigationController visibleViewController];

ABRecordRef person = displayVcardViewController.displayedPerson;

EditAddressNewPersonDetailViewController *newVCardViewController = [[EditAddressNewPersonDetailViewController alloc] init];
newVCardViewController.displayedPerson = person;
newVCardViewController.newPersonViewDelegate = self;
newVCardViewController.isEditingMode = YES;

[self.navigationController setToolbarHidden:YES];
[self.navigationController pushViewController:newVCardViewController animated:YES];
[newVCardViewController release];

Isn't this strong reference already or else Where should I include the strong reference.

On

- (void)actionSave:(UIBarButtonItem *)sender {

if([[NSBundle mainBundle] loadNibNamed:@"MyView" owner:self options:nil]) { 
    [self.myView setFrame:CGRectMake(0, 0, 320, 480)];

    [[UIApplication sharedApplication].keyWindow addSubview:self.myView];

           UIActionSheet * action = [[UIActionSheet alloc]initWithTitle:@""
                                                              delegate:self
                                                     cancelButtonTitle:@"Do"
                                                destructiveButtonTitle:@"Cancel"
                                                     otherButtonTitles: nil];
           action.tag = 101; 
          [action showInView:self.view];
          [action release];
}

}

I am loading a UIView with UIAlertView over it.


Solution

  • Update: Starting with iOS 7.0, ABNewPersonViewController is not subclassable anymore and this won't work.

    First, keep a reference to the default rightBarButtonItem before overriding it. If you're subclassing ABNewPersonViewController, your viewDidLoad would look like:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // Store the old button item into a custom property
        // @property (nonatomic, retain) UIBarButtonItem *defaultRightBarButtonItem;
    
        self.defaultRightBarButtonItem = self.navigationItem.rightBarButtonItem;
    
        UIBarButtonItem *saveBtn = [[UIBarButtonItem alloc] 
                                    initWithBarButtonSystemItem:UIBarButtonSystemItemSave 
                                    target:self 
                                    action:@selector(actionSave:)];
        self.navigationItem.rightBarButtonItem = saveBtn;
        [saveBtn release];
    }
    

    And you call the default action on the default target in your custom action method:

    - (void)actionSave:(UIBarButtonItem *)sender {
    
        // Do what you want to do before the data is saved
        // ....
        // ....
    
        // Trigger the default action
        [self.defaultRightBarButtonItem.target 
         performSelector:self.defaultRightBarButtonItem.action
         withObject:self.defaultRightBarButtonItem.target];
    }