My app is is designed to handle the PDF files. Whenever user opens a PDF file I would like to redirect the him/her to appropriate ViewController.
I tried several different approaches and I noticed interesting behavior.
Whenever I reference the navigation controller using window everything works fine:
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController pushViewController:_importer animated:YES];
But when I use storyboard
UIStoryboard *st = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UINavigationController * nav =(UINavigationController *)[ st instantiateInitialViewController ];
[nav pushViewController:_importer animated:YES];
It doesn't work. Why?
instantiateInitialViewController creates a new instance of the initial view controller of your storyboard. At that point, its view is not part of the view hierarchy. The pushing works just fine, I'm sure, but since the navigation controller isn't on screen, you won't see the new view controller get pushed.
Related
I added a Navigation Controller to my storyboard and it appears like so:
Now in the table view controller, I gave the TableViewController a storyboard id and class to a TableViewController Controller
When I run my app, I don't see the Navigation Bar at the top. This has been extremely frustrating and can't find a solution anywhere. PLEASE HELP
To get to the scene, someone clicks a button and this code runs and it goes to my Table View Controller:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
LHFileBrowser *LHFileBrowser = [storyBoard instantiateViewControllerWithIdentifier:#"FileBrowser"];
[self.navigationController pushViewController:LHFileBrowser animated:YES];
[self presentViewController:LHFileBrowser animated:YES completion:nil];
The error is in your code.
If you want to (modally) present a view controller when the user presses a button, you need to present the navigation controller (which will contain the table view controller), not the table view controller itself.
Right now, you're presenting the view controller, which won't show it being embedded in a navigation controller.
Also, you're mixing up two different approaches, by trying to push a view controller onto a navigation controller stack, and also presenting the view controller.
Code Sample:
Here's what you apparently mean to do:
UIStoryboard *storyboard = self.storyboard;
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"MyNavigationControllerID"];
LHFileBrowser *rootViewController = [navigationController topViewController];
// Configure your LHFileBrowser view controller here.
rootViewController.someProperty = ...;
// Modally present the embedded view controller
[self presentViewController:navigationController animated:YES completion:nil];
If you want to change the presentation or transition style, you can set those details in your storyboard.
You didn't explain why you had to programmatically add buttons, but Storyboard segues would have instantiated and presented an embedded view controller for you, without you having to have done it in code.
The more you can do in Storyboard, the less code you have to maintain, support, and update, and the more likely your app will still work properly when a new SDK is released.
Update:
The better way to do this is to let Storyboard do it for you, by adding a segue from the button to the navigation controller that you want to present.
I am handling push on alert to jump/open a view in story board like this from delegate
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:#"Main_iphone4" bundle:nil];
ChatViewController *scvc = (ChatViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ChatViewController"];
[self.window.rootViewController presentViewController:scvc animated:YES completion:nil];//not working show nothing while it works to jump using simple xib views.
and if i use
self.window.rootViewController =scvc;//it works but i need to get back on back button which causes it to get back in blank screen.
How to jump to a view controller using storyboard on handling push from delegate.
NOTE: The jump view have a back button,which need to dismiss the view too.
NOTE APP IS NOT NAVIGATION BASED
I've created a new XCode project using the SplitViewNavigator template. One of the MasterViewController's navigationItems should present a configuration ViewController (fullScreen on iPhone, popup on iPad).
This config controller has been created in a separate storyboard (Filter.storyboard).
In this storyboard I dragged a ViewController on the stage and embedded it in a Navigation Controller (Editor -> Embed In -> Navigation Controller) because the config itself consists of different screens the user can go through.
The NavigationController has been given a StoryBoard ID "FilterNavController".
I've done this several times in other applications, so this does work. Unfortunately, I can't get it working with the SplitViewNavigator template.
Here is how I try to open the filter controller once the button has been tapped, nothing special about it;
UIStoryboard *filterBoard = [UIStoryboard storyboardWithName:#"Filter" bundle:nil];
UINavigationController *filterNavController = [filterBoard instantiateViewControllerWithIdentifier:#"FilterNavController"];
UIViewController *vc = [filterNavController.viewControllers objectAtIndex:0];
[self.navigationController presentViewController:vc animated:YES completion:nil];
self is the MasterViewController.
From my uneducated point of view, I don't see any reason why this wouldn't work. As I said, it does in other (non SplitViewNavigator template) applications.
The error message I'm getting is the following:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <UINavigationController: 0x7f9bab61a700>.'
No idea what the heck is going on here but it already cost me half a day.
Interestingly, when I just create a UIViewController on the Filter.storyboard and set its StoryBoardID, the ViewController will get presented. However, I need it to be embedded in a UINavigationController.
Any help would be highly appreciated!
For the sakes of completeness, the following method works nicely for instantiating ViewControllers from a Storyboard.
Instead of creating a UINavigationController on the Storyboard, just create the ViewController(s) and embed them in a UINavigationController on code.
UIStoryboard *myBoard = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
MyViewController *menuController = [myBoard instantiateViewControllerWithIdentifier:#"MyViewController"];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myController];
[self presentViewController:navController animated:YES completion:nil];
If I show a viewcontroller in iOS using instantiateViewControllerWithIdentifier, I can not leave the viewcontroller without crashing. The view loads fine and performs its tasks but when i try to leave it by pushing a button the app crashes. Is this because of some state that is wrong or have i made another mistake?
Code:
- (IBAction)push:(id)sender {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:[[NSBundle mainBundle].infoDictionary objectForKey:#"UIMainStoryboardFile"] bundle:[NSBundle mainBundle]];
NSLog(#"story: %#",mainStoryboard.description);
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
ListViewController *controller = (ListViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"ListId"];
appDelegate.window.rootViewController = controller;
}
You're changing the applications root view controller as a result of pressing a button on the previous root view controller. That's not really how navigation in an iOS app should be done. Instead, try embedding your root view controller in a UINavigationController and then push and pop view controllers through it to navigate around your app.
If your interface doesn't fit a navigation paradigm, you could use presentViewController:animated:completion:.
Regardless, you should read the View Controller Programming Guide as it addresses the best practices of displaying views.
In my app I have an ECSlidingViewController declared as initial root controller via Storyboard. In my AppDelegate's didFinishLaunchingWithOptions method, I instantiate it as above:
self.slidingController = [[UIStoryboard storyboardWithName:#"AppStoryboard" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"ECSlidingViewController"];
What I want is to be able to show a global modal view controller (eg. when a push notification arrives while the app is active) without knowing which controller is currently top in the sliding controller.
What I do is (in my AppDelegate):
[self.slidingController.topViewController presentModalViewController:controller animated:YES];
but it doesn't seem to work.
Is there any way I could present a modal controller from my sliding controller regardless which controller is topViewController?
PS. If no, is there any chance that what I want will work with SWRevealViewController instead of ECSlidingViewController? If it's worth, I will take the painful road to switch.
Thank you in advance!
If the ECSlidingViewController is set as the initial view controller in the storyboard, then why are you instantiating another one in your app delegate code? By doing that, you're calling your methods on a different instance of ECSlidingViewController than the one that's put on screen by the storyboard. This is likely the source of your problem. Instead, get a reference to your ECSlidingViewController like this:
self.slidingController = self.window.rootViewController;
Then try,
self.slidingController.topViewController presentModalViewController:controller animated:YES];
or
self.slidingController presentModalViewController:controller animated:YES];
I haven't worked with ECSlidingViewController, so I don't know which of these might work.
Try this
UIViewController *rootViewController = self.window.rootViewController;
// You now have in rootViewController the view with your "Hello world" label and go button.
// Get the navigation controller of this view controller with:
UINavigationController *navigationController = rootViewController.navigationController;
[navigationController.topViewController presentModalViewController:controller animated:YES];