I have a NavigationController as Initial View and a ViewController as the root view. From that root view i am trying to do a segue with:
[self.navigationController performSegueWithIdentifier:#"Segue" sender:self];
There´s another view controller in my storyboard and i gave the segue the correct identifier. On iOS 8 it works perfect, but on iOS 7 it crashes with the following message:
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Could not find a navigation controller for segue 'Segue'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
I don´t get why it´s not working on iOS 7...
UPDATE: Here´s my Storyboard:
The problem is, that your segue has the UINavigationController as its source.
A UINavigationController should not perform a segue. It should only be connected to a rootViewController, which may be a UIViewController (or its subclass). A segue should be performed from the rootViewController of the UINavigationController. The segue should have the rootViewController as its source and some other UIViewController (or its subclass) as its destination.
Your screenshot shows that your UINavigationController is connected to a rootViewController. You now need to set the rootViewController as the source of the segue (having identifier Segue), which currently has your UINavigationController as its source. Now, from the rootViewController, call
[self performSegueWithIndentifier:#"Segue" sender:nil]
Do this:
[self performSegueWithIdentifier:#"Segue" sender:self];
use Self if you are already performing segue from within the rootViewController.
If not then try this .
[self.navigationController.viewControllers[0] performSegueWithIdentifier:#"Segue" sender:nil];
Hope this will help you.
I think you have no segue in storyboard from rootViewController to other viewController with name #"Segue".
Related
I'm calling a method in AppDelegate from a modal view to switch to rootviewcontroller (TabBarController) after an event occurs. How can I bring the rootview to the foreground? I shouldn't create a new instance of rootviewcontroller.
You can access the instance of the applications rootViewController using self.window.rootViewController
Im trying to return to a specific ViewController in it's current state after going from that ViewController to another using presentViewController.
But when I try to close the other ViewController (with dismissViewController) I get a white screen.
RootViewController *rootViewController
= [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil]
instantiateViewControllerWithIdentifier:#"RootViewController"];
[self presentViewController:rootViewController animated:YES completion:nil];
This isn't an option either because that instantiates a new viewcontroller and I want the old ViewController in its current state.
Do I need to pass the RootViewController as an argument when presenting the other ViewController or is there another option to return to the RootViewController in its current state?
Yes, there is a way to return original screen.
I met just like problem but solved it with following code line
[self dismissViewControllerAnimated:YES completion:nil];
one way to address this is to avoid having one view controller responsible for presenting and dismissing the other one.. what you can do is create a controller of controllers (give it a singelton method).. and have that object basically keep a reference to any view controller you are interested in maintaining its state. That way you wouldn't have worry about what's going on behind the scenes when you dismiss or present a view controller.
The start of the structure is as follows...
UITabBarController -> UINavigationController(s)
From each of the UINavigationControllers, I have a UIBarButtonItem that modally presents a UIViewController.
This UIViewController has a MKMapView with pins at multiple locations. When clicked, they display an annotation with a disclosure button.
Within this UIViewController, it is my intention to push a detail page (UITableViewController) when pressing the disclosure button of the annotation. The method calloutAccessoryControlTapped: receives the appropriate pin, but the transition to the next controller fails.
I have tried every combination of the following methods...
[self.navigationController ...]
[self.parentViewController ...]
[self.parentViewController.navigationController ...]
with the method being either...
presentModalViewController:
pushViewController:
I have done all of these with the UIViewController being on its own, and also with it embedded inside of a UINavigationController.
All of these properties return null...
self.navigationController
self.parentViewController
self.parentViewController.navigationController
This is the first time I've used storyboard for an Xcode project. Am I missing a step?
Try getting rid of the code and implementing the transitions in storyboard by control dragging from the button to the view controller you wish to load modally. When the "Storyboard Segue" menu pops up select "modal". In the modal view controller, I like to use code to return from the modal by calling:
[self dismissModalViewControllerAnimated:YES];
To Presenting Storyboard View Controllers Programmatically scroll to that section in gravityjack on the link provided.
For example, I have a view controller that I created in storyboard which I can call programmatically with the following two statements:
SettingsViewController *settingsVC = [self.storyboard instantiateViewControllerWithIdentifier:#"settingsVC"];
[self.navigationController pushViewController:settingsVC animated:YES];
I have a table view, and in one of the cells, it says "contact". Upon selecting this cell, I'd like to push in a MFMailComposeViewController.
I can only seem to present this MFMailComposeViewController modally. What is the problem here?
Thanks!
Relevant code frag:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
//*works*//[self.navigationController presentModalViewController:controller animated:YES];
//*broken*//[self.navigationController pushViewController:controller animated:YES];
}
The error that I get is: " * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'
* Call stack at first throw:"
So it looks like I have a navigationController already, and since MFMailComposeViewController is a subclass of UINavigationController, I'm pushing a navController onto another navController?
I want my UI to be consistent, so I want to push a MFMailComposeViewController onto the nav stack rather than present it modally.
This is because MFMailComposeViewController isn't a subclass of UIViewController but of UINavigationController. UINavigationController throws an exception when you're attempting to push a UINavigationController or subclass of UINavigationController onto an existing stack. Presenting a UINavigationController modally is permitted.
According to Apple documentation
To display the view managed by this view controller, you can use any of the standard techniques for displaying view controllers
So what you are trying to do is supposed to work in both cases. Did you have a look at the logs ?
I would have bet your navigationController is nil, because this typically happens when you are using a plain UIViewController (not embedded in a UINavigationController, but it you actually present your modal view onto the navigationController, it may not be nil.
I'm pushing a number of views:
the top one is a UITabBarController
the second one is a UINavigationController with a pushed view
the third one is a modal box.
Once the close button in the modalbox is pressed I'm trying to revert everything to the default state and change the tabbar index.
[self dismissModalViewControllerAnimated:YES];
[self.navigationController popViewControllerAnimated:NO];
[self.tabBarController setSelectedIndex:3];
This dismisses the modal view but doesn't do anything else. Any ideas what could be wrong? I read something about a possible ios bug but I don't know how to work around it.
Neither UITabBarController nor UINavigationController is a view. Both are subclasses of UIViewController and have a property NSArray *viewControllers.
If you have an actualView controlled by an ActualViewController that is pushed on top of a rootView controlled by a RootViewController that is the rootViewController for the navigationController, and you also have a modalView controlled by a ModalViewController, then put
[self dismissModalViewControllerAnimated:YES];
in ModalViewController.m, and put
[self.navigationController popViewControllerAnimated:NO];
in ActualViewController.m (from whence modalView is pushed, presumably), and put
[self.tabBarController setSelectedIndex:3];
in RootViewController.m (from whence actualView is pushed, presumably).
If modalViewController was never added to the navigationController, then it doesn't know that the navigationController exists.
If actualViewController was never added to the tabBarController, then it doesn't know that the tabBarController exists.
The easy (and dirty) way:
Dismiss the modal view in the modal view. Make the navigation view controller the delegate of the modal view. Make the tabbar controller the delegate of the navigation controller. When the button is pressed call a method in the navigation controller that pops the view and calls a method of the tabbar controller which changes the selected tab.