1

I am working on an app whose main UI is based on a tab bar controller.

In one of the tabs I have a collection view, which drills down to a detail view via a navigation controller.

What I am trying to do is upon receipt of a push notification I would like to select this specific tab, fetch the latest data from the server, find the particular item to display, then push the detail view on to the screen to display said item.

My problem is I get the following message after collectionView:didSelectItemAtIndexPath:

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

Here is what I am doing so far:

App Delegate application:didReceiveRemoteNotification:

[self selectFavouritesTab];
NHFavouritesViewController *favouritesViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"Favourites"];
[favouritesViewController displayFavouriteForPushNotificationWithId:favouriteId];

From FavouritesViewController - After fetching the latest favourites, I send a message to displayFavouriteItemWithId:

- (void)displayFavouriteItemWithFavouriteId:(NSNumber*)favouriteId
{
    NSArray* results = [_collectionViewData filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF.favouriteId == %@", favouriteId]];

    NSInteger row = [_collectionViewData indexOfObject:[results lastObject]];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
    [[self collectionView] selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];
    [self.collectionView.delegate collectionView:self.collectionView didSelectItemAtIndexPath:indexPath];
    [self performSegueWithIdentifier:@"FavouriteItem" sender:self];
}

And it is at this point it crashes. I understand what the crash message is saying, however what I don't know is how to place NHFavouritesViewController inside a navigation controller (which is embedded inside one in the storyboard) when I respond to the push notification in the app delegate?

Nick
  • 939
  • 1
  • 12
  • 19

2 Answers2

1

The problem that you're having is that you are not instantiating the navigation controller.

By loading the favourites view using that method you are literally only creating that one view controller.

So then when you are telling it to push it can't because you didn't instantiate the navigation controller from the storyboard.

The chances are that the navigation controller already exists so you need to get hold of that instead of creating new controllers.

I'm on a mobile right now so can't answer fully but let me know if you're still struggling and I'll see if I can ad done code. Will prob need to see more code first though.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • I appreciate what you say, however I am unsure how to instantiate the navigation controller from the storyboard, then send messages to methods in NHFavouritesViewController, which will then use said navigation controller. If you are able to help when available that would be great. – Nick Oct 04 '14 at 11:22
1

You can wrap a view controller in a standard navigation controller with:

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:favouritesViewController];

But I can't see from your code above how favouritesViewController is presented in the tabBarController. If you are doing it in a storyboard, then just drag in a blank navigation controller, hook the relevant tab of your tabBarController to the navigation controller (Ctrl-drag, then select "Relationship segue: viewControllers", and then hook from the navigation controller to your FavouritesViewController (likewise).

EDIT:

If that is already done in the storyboard, then you need to amend your code to pickup the existing version of NHFavouritesViewController, instead of instantiating new. Something like (assuming you have a reference to your Tab Bar Controller in self.tabBarController, and the favouritesViewController is in the tab with index favouritesTab (I assume you can get these, since you already have a method to select the tab):

UINavigationController *navController = (UINavigationController *)self.tabBarController.viewControllers[favouritesTab];
NHFavouritesViewController *favouritesViewController = (NHFavouritesViewController *) navController.rootViewController;
pbasdf
  • 21,386
  • 4
  • 43
  • 75
  • Yeah, I know you can do that, however my problem is where I do this, as of course I initially respond to the notification in the app delegate, which is where I send the message to favouritesViewController. I send a message to selectFavouritesTab (as above) to select the favourites tab, which simply sets the selectedIndex of tabBarController which is the root view controller of the application. FavouritesViewController is already embedded in a navigation controller in the storyboard, which is connected to the tab bar controller. – Nick Oct 04 '14 at 11:40
  • In your AppDelegate code you are creating a completely new FavouritesViewController, which is not embedded in the NavigationController. Hence the error. You need to obtain a reference to your existing FavouritesViewController, not instantiate a new one. To do that, you can use the viewControllers property of your tabBarController. – pbasdf Oct 04 '14 at 11:44
  • Thank you so much, a schoolboy error on my part ;-) Add your last comment in to your answer then I will accept it. – Nick Oct 04 '14 at 11:57