I have an iOS 5 Tabbed Application, using Storyboards.
My Tabbar Controller points to three Navigation Controllers.
From one of them, the flow looks like this:
Start view --> Photo view (modal) --> Catalog view
On the photo screen, I have a button with the following code:
- (IBAction)acceptPhotoButtonPressed:(id)sender {
UIViewController *catalogView = [self.storyboard instantiateViewControllerWithIdentifier:@"CatalogView"];
[self.navigationController pushViewController:catalogView animated:YES];
}
I've tried fooling around with presentingViewController
, parentViewController
- even type casted those to a UINavigationController
. That causes it to crash, with the following error message:
2012-04-06 00:32:45.808 myapp[19345:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITabBarController pushViewController:animated:]: unrecognized selector sent to instance 0x18d0d0'
So that tells me that I haven't got hold of a UINavigationController
, but a UITabBarController
.
Is there any way around this?
A "push" style segue can only be done from a view controller that is being managed by a UINavigationController
. If you try to do so otherwise nothing will happen.
Instead of displaying your Photo view modally as you describe in your question, you should display an instance of UINavigationController as the modal view and make the Photo View the root view controller of the navigation view. (This can all be set up through storyboard). Then your push segue will work.
If you do not wish for the top navigation bar to appear on your first view controller (Photo view) you can use:
[self.navigationController setNavigationBarHidden:YES animated:NO]
This will hide top nav bar. Once you push a new view controller, if you want the nav bar to reappear on that one and any subsequent view controllers you'll have to set setNavigationBarHidden to NO on the new viewcontroller.
[self.navigationController setNavigationBarHidden:NO animated:NO]
Segue's are the preferred way of transitioning from one scene to another.
You could either create a Segue from that button or from the VC itself and connect that segue to the scene you want to push. Make sure the Segue property is set to Push and then in the button's IBAction (assuming you connected to the VC) do this:
- (IBAction)acceptPhotoButtonPressed:(id)sender {
[self performSegueWithIdentifier@"mySegueID" sender:nil];
}
then in the prepareForSegue method:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString@"mySegueID"]) {
// Do whatever setup you need to do before firing the segue
}
}
If you connect the Segue to the button itself, then you can eliminate the performSegue method altogether (you really don't even need that IBAction).