This question already has an answer here:
presentViewController does not show Tab Bar or Navigation Bar
(1 answer)
Closed 7 years ago.
I am using following code to launch a view controller modally. This view controller is not being created from scratch. Rather, I created and styled it in storyboard, gave it a name, embedded it in a navigation controller so it has a navigation bar and created cancel and done buttons, gave it a title and the code below launches it.
The problem is that while most of the features of the screen show up such as labels and images, the title and navigation bar that you can see in the storyboard disappear. Has anyone come across this issue and have a fix for it?
My code to launch VC created in storyboard.
- (void) editView:(id) sender
{
NSLog(#"launch button pressed");
UIStoryboard *storyBoard = self.storyboard;
IDEditVC *editVC =
[storyBoard instantiateViewControllerWithIdentifier:#"editvc"];
editVC.item = _item;
[self presentModalViewController:editVC animated:YES];
}
I think what's happening is that since you are directly instantiating the view controller by name it's getting just that from the storyboard rather than embedding it in the nav controller.
Try this:
In your storyboard, make the Navigation Controller the initial/root View Controller for the storyboard
Instead of instantiating by name, use UIStoryboard's instantiateInitialViewController method.
EDIT:
Based on your comments below, you might want to try this:
- (void) editView:(id) sender
{
NSLog(#"launch button pressed");
UIStoryboard *storyBoard = self.storyboard;
IDEditVC *editVC =
[storyBoard instantiateViewControllerWithIdentifier:#"editvc"];
editVC.item = _item;
UINavigationController *nav = [UINavigationController alloc] initWithRootViewController: IDEditVC];
// Do whatever setup you want to here for your title bar, etc
[self presentModalViewController:nav animated:YES];
}
Try to use PushViewController instead of instantiate:
How to push viewcontroller ( view controller )?
Good luck
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.
In my app, I dynamically load a set of images, and when a user taps on an image, it opens up a new ViewController (MediaPreview) that opens up a large preview of the image.
I create the MediaPreview controller as follows:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
mediaPreviewVC = (MediaPreviewViewController *)[storyboard instantiateViewControllerWithIdentifier:#"MediaPreviewViewController"];
mediaPreviewVC.selectedImageURL = [NSString stringWithFormat:#"%#",gestureRecognizer.view.tag];
navigationController = [[UINavigationController alloc] initWithRootViewController:mediaPreviewVC];
[self presentViewController:navigationController animated:YES completion:nil];
This creates a ViewController that looks like this:
However, the bottom navigation bar appears to be missing, which is outlined in my storyboard:
How can I ensure that the bottom navigation bar buttons appear in my view?
You are creating the navigation controller out of whole cloth:
navigationController = [[UINavigationController alloc] initWithRootViewController:mediaPreviewVC];
alloc-init means "make me a completely fresh, separate, generic one". Thus, navigationController is not the navigation controller in your storyboard. It's a completely new and different navigation controller. Thus, what's in your storyboard is irrelevant.
If you wanted the navigation controller from your storyboard, you needed to instantiate the navigation controller from the storyboard. Or, if you're doing this intentionally, then the bottom bar won't be visible unless you explicitly make it visible, because by default it isn't (it's obvious how to make it visible explicitly).
But then in that case, if you meant to pull it out of the storyboard, then your whole code is probably wrong, because the one in the storyboard probably already has the correct root view controller as well.
I have a storyboard in my application with a navigation controller and several views. This automatically puts a navigation bar with a back button into any views that are not the root view.
However, sometimes I navigate away from this storyboard to an individual nib. I want to navigate back to the storyboard, but not necessarily to the original root view. I currently use this method to do so:
+(void) TransitionOnStoryboard:(NSString*)storyboard to:(NSString*)identifier withViewController:(UIViewController*)viewController
{
UIStoryboard *sb = [UIStoryboard storyboardWithName:storyboard bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:identifier];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[viewController presentViewController:vc animated:YES completion:NULL];
}
This shows the view I want but without the navigation bar. How do I specify my navigation controller or root view, such that the app knows to put a navigation bar with a back button in?
Thanks
The answer is to leave your navigation controller underneath the view controller you add from a nib.
Present the nib as a full0-screen modal. That gets rid if your navigation bar, as desired. From that new view controller, you can push more modals, add a navigation controller, or whatever.
Note that you could do all of this and stay inside your storyboard as well.
Once you are done, dismiss the modal to reveal your navigation controller, and you are back in business with your storyboard. You can push a new view controller onto your navigation controller without animation and it should appear as the front-most VC when you pop the modal that came from a nib.
I'm sure that this isn't the ideal way to solve this problem, but it did work very nicely for me.
Essentially, I removed all the views from the view controller that had been generated since I navigated away from the storyboard, but before the current view and popped the current view. In this case, these views were of one class (CheckboxListViewController) and so could be removed quite simply as below:
+(void) navigateToMainMenu:(UINavigationController*)navigationController
{
[QuickView removeFromNavigationController:navigationController allOfViewControllerWithClass:[CheckboxListViewController class]];
[navigationController popViewControllerAnimated:YES];
}
+(void) removeFromNavigationController:(UINavigationController *)navigationController allOfViewControllerWithClass:(Class)viewControllerClass
{
NSMutableArray *keptViewControllers = [[NSMutableArray alloc]init];
for (UIViewController *viewController in navigationController.viewControllers)
if (![viewController isKindOfClass:viewControllerClass])
[keptViewControllers addObject:viewController];
navigationController.viewControllers = keptViewControllers;
}
(note- QuickView is the name of the class that contains these methods.).
Any other classes that you do not want your pop to navigate back to can be removed by calling:
[QuickView removeFromNavigationController:navigationController allOfViewControllerWithClass:[YourClassName class]];
In the navigateToMenu method.
My app starts with a navigation controller which opens a UIViewController. This screen works as a login page.
On login, I open a UITabBarController like this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UITabBarController *obj=[storyboard instantiateViewControllerWithIdentifier:#"MainTab"];
self.navigationController.navigationBarHidden=YES;
[self.navigationController pushViewController:obj animated:YES];
Inside my tab bar controller, I want when clicking a button to switch tab programmatically. I tried the following 3, neither of them worked. Code is place inside a method, which is invoked when the button is clicked.
For the first 2, the tab didn't change - still my initial tab is highlighted and the correct view controller is not shown. For the last one, app crashes.
1st :
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:1];
2nd :
[self.parentViewController.tabBarController setSelectedIndex:1];
3rd:
UITabBarController *MyTabController = (UITabBarController *)((AppDelegate*) [[UIApplication sharedApplication] delegate]).window.rootViewController;
[MyTabController setSelectedIndex:1];
What am I missing?
for a tabBar inside a navigation controller...What am I missing?
One thing you're missing is the order of containment that's allowed for view controllers. Specifically, you can put a navigation controller inside a tab controller, but not the other way around.
I am having a problem with this.
In my root view controller I am having a textfield & one button. I am giving a condition like if i entered 0 in textfield then only it should move to next view.
upto here it is working correctly. But now here is problem. Here I am having one button & given navigation to third view controller for that button. here i am getting error as
Terminating app due to uncaught exception 'NSGenericException', reason: 'Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
image ref: http://img12.imageshack.us/img12/8533/myp5.png
and i am giving action for button in first view as below
- (IBAction)Submit:(id)sender {
if([tf.text isEqual:#"0"])
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID" ];
[self presentViewController:vc2 animated:YES completion:NULL];
}
}
Go To:
Editor--> Embed In --> Navigation Controller, to add Navigation Controller to your initial view
After looking at your screenshot, you either need to
Push your SecondViewController onto the existing navigation controller's stack instead of presenting it modally OR
You need to embed your SecondViewController in another navigation controller and then create and present that navigation controller modally from your SamplesViewController
Either way, SecondViewController needs to be embedded in a navigation controller before you can use Push Segues from it
Either embed your view controller in a Navigation controller or if there is a Navigation controller in the story board mak it the initial view controller
I also faced same problem. My problem was I was using model segue style (rather that push) for one before the current controller because of that I think it broke the Navigation chain before already.
Embed your view controller in a UINavigationController is a good option if there is no UINavigationController in the storyboard. Otherwise you can select the UINavigationController and select the root view controller in the inspector pane, then drag it to the UIViewController you want to use as root. the screenshot is as below:
I solved this by creating a custom UIStoryboardSegue between the UINavigationController and the destination view controller:
-(void) perform
{
assert([self.sourceViewController isKindOfClass:[MyNavigationController class]]);
MyNavigationController *launchController = (MyNavigationController *) self.sourceViewController;
[launchController setViewControllers:#[self.destinationViewController] animated:YES];
}
Try this. It works for me.when you set root view controller to first view and use self.presentViewController ,controller move to next view but instance of navigation controller is only for first view,third view required navigation instance so use self.navigationController instead of presentViewController.
NSString * storyboardName=#"Main";
UIStoryboard *storybord=[UIStoryboard storyboardWithName:storyboardName bundle:nil];
SecondViewController *vc=[storybord instantiateViewControllerWithIdentifier:#"SecondViewControllerID"];
[self.navigationController pushViewController:vc animated:YES];