iOS - Display view after push notification is rece

2019-08-10 17:44发布

问题:

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?

回答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;


回答2:

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.