dandoen
dandoen

Reputation: 1647

Calling parent method from a modal or push view to presentingViewController

I have a UINavigationGroup with a root view controller called MainViewController. Inside this MainViewController I'm calling another UINavigationController as a modal as following:

- (IBAction)didTapButton:(id)sender {
    UINavigationController * someViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"someNavigationController"];
    [self.navigationController presentViewController:someViewController animated:YES completion:nil];
}

Inside this someNavigationController, the user is going through some process so the nav controller is being pushed with some UIViewControllers. After the user completes the process, in the last UIViewController called finalStepViewController, I'm closing the modal as follow:

[self dismissViewControllerAnimated:YES completion:nil];

The modal is indeed dismissed and the user is back to the initial MainViewController. However, I'd like to push another UIViewController to MainViewController's NavigationController (for example: a view saying that the user completed the process successfully). Preferably before the modal is dismissed.

I have tried the following things:

1. Using presentingViewController

UIViewController * successViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"successViewController"];
[self.presentingViewController.navigationController successViewController animated:YES];

Result: no error, but nothing happening either.

2. Delegate/protocol

Result: except for the notice error, no fail but nothing happens as parentMethodThatChildCanCall is not called.

Any idea what I'm doing wrong/what I should be doing? It's my second week doing Objective-C, and most of the time I don't know what I'm doing so any help/code would be appreciated!

Thanks.

Upvotes: 1

Views: 621

Answers (1)

Eugene
Eugene

Reputation: 10045

You can achieve this a lot easier using NSNotificationCenter.

In your MainViewController's -viewDidLoad add the following code

  typeof(self) __weak wself = self;
  [[NSNotificationCenter defaultCenter] addObserverForName:@"successfullActionName"
                                                    object:nil
                                                     queue:[NSOperationQueue mainQueue]
                                                usingBlock:^(NSNotification *note) {
                                                  SuccessViewController *viewController; // instantiate it properly
                                                  [wself.navigationController pushViewController:viewController animated:NO];
                                                }];

Remove your controller from NSNotificationCenter upon dealloc

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

In FinalStepViewController on action that dismisses the view controller before dismiss post the notification

- (IBAction)buttonTapped:(id)sender {
  [[NSNotificationCenter defaultCenter] postNotificationName:@"successfullActionName" object:nil];
  [self dismissViewControllerAnimated:YES completion:nil];
}

This example is very crude and is not ideal, you should use constants for your notification names and in some cases store the observers returned by NSNotificationCenter to remove specific ones.

-- EDIT I'd like to also mention that the method addObserverForName:object:queue:usingBlock: actually returns the observer as an id type object. You need to store a reference to it as an iVar in your class and remove it from the NSNotificationCenter when dealloc method is called otherwise that observer will never get deallocated.

Upvotes: 1

Related Questions