navigation controller issue in application with 2 tabs - ios

In my application 2 tabs are there. I am adding tabbarController to the window with two view controllers viewcontroller1 and viewcontroller2 in didFinishLaunchingWithOptions. Now I need to add a button in the viewcontroller1 and in the button action i need to push a new viewcontroller nextViewController. To do this in the button action, i had created a navigation controller and sets its rootview controller as viewcontroller1 and then i push the nextViewController through that navigation controller. But the nextViewController is not getting loaded. Why?
(void) buttonAction {
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:self];
nextViewController *nextViewControllerObj = [[nextViewController alloc]init];
[self.navigationController pushViewController:nextViewControllerObj animated:YES];
}

Instead of adding first tab view controller into UINavigationController, please try adding main UITabBarController into UINavigationController in "didFinishLaunchingWithOptions".

Related

PresentViewController from a presentedViewController is not showing navigation bar

I have three view controllers (vc1, vc2, vc3) and two navigation controllers (nav1, nav2).
nav1 is the entry point of the storyboard.
vc1 is the rootViewController of nav1.
vc2 is the rootViewController of nav2.
nav2 is presented from vc1 through nav1.
Now when I tried to present vc3 from vc2 through nav2, navigation bar is not showing.
You need to present your controller with navigationController.
ViewController *objVC = [self.storyboard instantiateViewControllerWithIdentifier:#"viewcontrollerid"];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:objVC];
[self.navigationController presentViewController:navController animated:YES completion:nil];
Now, the way iOS works, it will never give you an instance of your navigation controller in a presented view controller because when you present a view controller, it is not added to the viewcontroller stack of the navigation controller.
The reason you can see the navigation controller in the other two is because your'e presenting the navigation controller itself and not view controller.

Can't push to View Controller from AppDelegate without losing Navigation Bar and Tab Bar setup iOS

I try to push to specific view controller from app delegate without losing previously set navigation bar and tab bar items setup.
As presented in my Main storyboard:
After 1 action performed in TypeNameVC, on app relaunch I want to skip LogInVC and TypeNameVC in didFinishLaunchingWithOptions in AppDelegate forward to MapViewController or any other VC of Tab Bar Controller.
This code initializes new Navigation Controller with new Navigation Bar and Tab Bar Controller is missing.
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
//To instantiate Main.storyboard.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
//To instantiate VC to go to.
MapViewController *mapVC = (MapViewController *)[storyboard instantiateViewControllerWithIdentifier:#"MapViewControllerID"];
//To push to instantiated VC.
[navigationController pushViewController:mapVC animated:YES];
I tried to performSegue using segue to Tab Bar Controller but on Navigation Controller stack there is only LoginViewController (I checked it with [navigationController viewControllers])
I read through entire Stack Overflow, I made dozens of combinations but I can't figure out the solution. I would appreciate any help/advice.
UPDATED QUESTION
Screen: screen
Have a look to the screen image. First row of screen shows how it looks like if I navigate "normally". Second row shows what happens if I push to MapVC from AppDelegate. What I need is to skip first two VC's with maintaining Navigation and Tab Bar bars setup.
When I navigate "normally" Tab Bar Controller and it's VC's get correctly allocated.
2016-06-08 12:37:44.394 Checkpoint[4196:1034786] Navigation Controller VC's: (
LogInViewController: 0x135d50b00,
TypeNameViewController: 0x135f455b0,
UITabBarController: 0x135f1d180
)
2016-06-08 12:37:44.394 Checkpoint[4196:1034786] Tab Bar Controller VC's: (
MapViewController: 0x137078cf0,
PlacesTableViewController: 0x135f1d7d0,
FriendsTableViewController: 0x137083350
)
When I push directly to MapVC they don't. I do get the point what's going on but I know how to code that solution.
Navigation Controller VC's: (
LogInViewController: 0x15fd5ccf0,
MapViewController: 0x15fd6ffa0
)
2016-06-08 12:31:53.813 Checkpoint[4187:1033755] Tab Bar Controller VC's: (null)
Customize your class MapViewController for visible Navigation Bar and Tab Bar:
- (instancetype)init
{
// init code
self.hidesBottomBarWhenPushed = NO;
retur self;
}
-(void)viewWillAppear:(BOOL)animated
{
// some code
[self.navigationController setNavigationBarHidden:NO];
}

SWRevealViewController - push next view controller storyboard

I have a sidebar menu, made with SWRevealViewController.
I want to switch from the view controller and the view with the button to the next view controller. How I do that?
I try to used the ACTION SEGUE: "push", "modal", "revealview controller" and "revealview controller push controller".
But it doesn't works.
And I try it programmatically switch to the next viewcontroller.
MY CODE:
ViewController2 *vc2 = [[ViewController2 alloc] init];
[self.navigationcontroller pushViewController:vc2 animated:YES]
This change the ViewController, but without the view (blackscreen).
It seems ViewController2 is a ViewController in storyboard. Try the below code:
ViewController2 * vc2 = [[self storyboard] instantiateViewControllerWithIdentifier:#"ViewControllerId"];
You should give Storyboard ID for ViewController2 as ViewControllerId in your storyboard.
Please note that your current ViewController should be in a Navigationcontroller stack to call self.navigationcontroller.

'Push segues can only be used when the source controller is managed by an instance of UINavigationController

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];

Back to RootViewController from Modal View Controller

From Home view - my RootViewController - I open up 2 ViewControllers one after another as user progresses in navigation hierarchy like so:
1) SecondViewController is pushed by button connected in my Storyboard
2) ThirdViewController is presented modally
[self performSegueWithIdentifier:#"NextViewController" sender:nil];
So, the picture is: RootViewController -> SecondViewController -> ThirdViewController
Now in my ThirdViewController I want to have a button to go back 2 times to my RootViewController, i.e. go home. But this does not work:
[self.navigationController popToRootViewControllerAnimated:YES];
Only this guy goes back once to SecondViewController
[self.navigationController popViewControllerAnimated:YES];
How can I remove both modal and pushed view controllers at the same time?
I had a similar situation, where I had a number of view controllers pushed onto the navigation controller stack, and then the last view was presented modally. On the modal screen, I have a Cancel button that goes back to the root view controller.
In the modal view controller, I have an action that is triggered when the Cancel button is tapped:
- (IBAction)cancel:(id)sender
{
[self.delegate modalViewControllerDidCancel];
}
In the header of this modal view controller, I declare a protocol:
#protocol ModalViewControllerDelegate
- (void)modalViewControllerDidCancel;
#end
And then the last view controller in the navigation stack (the one that presented the modal view) should implement the ModalViewControllerDelegate protocol:
- (void)modalViewControllerDidCancel
{
[self dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popToRootViewControllerAnimated:YES];
}
This method above is the important part. It gets the presenting view controller to dismiss the modal view, and then it pops back to the root view controller. Note that I pass NO to dismissViewControllerAnimated: and YES to popToRootViewControllerAnimated: to get a smoother animation from modal view to root view.
I had the same requirement but was using custom segues between the view controllers. I came across with the concept of "Unwind Segue" which I think came with iOS6. If you are targeting iOS6 and above these links might help:
What are Unwind segues for and how do you use them?
http://chrisrisner.com/Unwinding-with-iOS-and-Storyboards
Thanks.
Assuming your AppDelegate is called AppDelegate, then you can do the following which will reset the rootviewcontroller for the app window as the view RootViewController
AppDelegate *appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
RootViewController *rootView = [[RootViewController alloc] init];
[appDel.window setRootViewController:rootView];

Resources