4

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.

Xavi Valero
  • 2,047
  • 7
  • 42
  • 80

1 Answers1

4

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];
}
Jilouc
  • 12,684
  • 4
  • 46
  • 43
  • I am not triggering the save button action inside the `- (void)actionSave:(UIBarButtonItem *)sender` method. Instead I am loading another view with buttons. And on the click of one of the buttons in view, another view loads. On the click of a button in this view, that I need to trigger the save button action. By the time I do this, the done button would be deallocated. Thats the problem I am facing. – Xavi Valero Mar 13 '12 at 18:39
  • 1
    Have you tried to keep a strong (retained) reference to the `ABNewPersonViewController` instance somewhere, as long as needed, preventing the controller from being deallocated? – Jilouc Mar 13 '12 at 18:53
  • My bad. I wasn't retaining the `defaultRightBarButtonItem`. I thought I had done that all these time. – Xavi Valero Mar 14 '12 at 05:56
  • When I try to save the edits, on certain occasions, the delegate method is not being triggered. What could be the reason for that? – Xavi Valero Mar 14 '12 at 06:28
  • Sometimes the method is not triggered. Especially the cases where I am trying to save the address details. What could be the reason for that. – Xavi Valero Mar 14 '12 at 13:15
  • Shall I post this as another question? – Xavi Valero Mar 16 '12 at 13:25
  • From the documentation: "Subclassing Notes: The ABNewPersonViewController class does not support subclassing." – de. Sep 04 '14 at 08:29
  • @de. you're right, as of iOS 7.0 it won't work because when you instantiate a ABNewPersonViewController, UIKit actually creates something else. I've been able to override the Done button on iOS 7+ but it involves so much runtime hackery that it's preferable not to share it. – Jilouc Sep 17 '14 at 14:26
  • @Jilouc would still be interesting though! – de. Sep 17 '14 at 19:05