0

I posted a question earlier today regarding reacting to the receipt of a push notification, whereby I needed to drill down from one view to another. This question was answered, however I have now moved on to another requirement for reacting to push notifications, whereby I need to drill down to a third level in the navigation stack.

Below is a mockup of my view hierarchy, where on receipt of the push notification I want to drill down to the view titles "Third View".

Screenshot of view hierarchy

From the answer to my previous question, I am able to drill down to "Second View", however when I try to perform the segue to push "Third View" on to the stack, I get the same type of error as per my previous question:

Terminating app due to uncaught exception 'NSGenericException', reason: 'Could not find a navigation controller for segue 'Admin'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'

In my AppDelegate, when I receive the notification I select the required tab then:

UINavigationController *navController = (UINavigationController*)[_tabBarController selectedViewController];
NHProfileViewController *profileViewController = navController.viewControllers[0];
[profileViewController displayAdminWebViewForPushNotification];

Then in profileViewController (First View) displayAdminWebViewForPushNotification:

_displayAdminForPushNotification = YES;
[self performSegueWithIdentifier:@"Settings" sender:self];

where "Settings" is "Second View" in the image above.

Then in prepareForSegue:

if ([segue.identifier isEqualToString:@"Settings"])
{
    NHSettingsTableViewController *settingsViewController = segue.destinationViewController;

    if (_displayAdminForPushNotification)
    {
        [settingsViewController displayAdmin];
        _displayAdminForPushNotification = NO;
    }
}

Up to this point all is fine, however as soon as I hit [settingsViewController displayAdmin]:

- (void)displayAdmin
{
    [self performSegueWithIdentifier:@"Admin" sender:self];
}

it crashes. I have done some debugging and at this point settingsViewController does not have a navigation controller (hence the crash/error message). This I don't understand as "First View" is embedded in a navigation controller.

Community
  • 1
  • 1
Nick
  • 939
  • 1
  • 12
  • 19

1 Answers1

1

Your performing the third segue to early -- the second segue isn't even done so it has no navigationController.

delay it by using this method to perform action after segue:
How to execute some code after a segue is done?

or use viewWillAppear!

Community
  • 1
  • 1
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
  • Thank you Daji-Dan. I can now get it to work by delaying [self performSegueWithIdentifier:@"Admin" sender:self]; in the "Second View", however am wondering if there is a better way of doing this, rather than through a delay (knowing when the second segue has finished)? You mention didPerformSegue, however I cannot find this method? – Nick Oct 04 '14 at 15:07
  • http://stackoverflow.com/questions/18310396/how-to-execute-some-code-after-a-segue-is-done sorry thats what I meant though – Daij-Djan Oct 04 '14 at 15:19
  • Ah, ok, thank you. I do have another question if you don't mind me asking: If I respond to a notification a subsequent time I end up with a message in the console "Unbalanced calls to begin/end appearance transitions for .", and the UI is all messed up - I now have two versions of "Second View" on the stack instead of "Second View" then "Third View". Any ideas? This happens both if I have navigated back to the root view or have stayed in "Third View". – Nick Oct 04 '14 at 15:34
  • The thing is taht you perform a push segue while another one is pending. You have to wait the first segue is done before fireing another one. To do that, fire your Admin segue in the second's VC viewDidAppear method. – Imotep Oct 04 '14 at 16:09
  • @Nick - to answer your ancillary question, I would check in your App Delegate method to see where you are in the controller hierarchy - if you check the class of the topViewController property of the navigation controller, you will be able to see whether it is First, Second or Third and choose your segue accordingly. If it is Third, you may not need a segue at all - just call a method to pass on the information from the push notification. – pbasdf Oct 04 '14 at 19:22
  • Excellent, thank you very much (again) Daij-Dan. You have helped immensely. – Nick Oct 05 '14 at 12:12