Present a ViewController that is embedded in Navigation Controller - ios

I have a situation wherein a storyboard made VC(embedded in NavController) should be presented programmatically.
SomeVC -> presents NavController(rootVC) -> rootVC -> pushes subVC
on this representation, subVC should have a back button to go back to rootVC, but I can't implement it this way. Will be providing sample codes that I have already tried.
this pushes the rootVC directly:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"storyBoard" bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"rootVC"];
[self.navigationController presentViewController:vc animated:YES completion:nil];
also tried pushing the navigationController itself, ID has been set on storyboard:
UINavigationController *navController = [storyboard instantiateViewControllerWithIdentifier:#"navigationController"];
[self presentViewController:navController animated:YES completion:nil];
EDIT: storyboard implementation looks like this

I'm not sure if I understand you correctly. You want to present a navigation controller and have those rootVC and subVC already in it, right? So after presenting, you want the subVC to be presented with the back button right away.
If that's the case you need to tell the navigation controller to push the subVC before presenting it
UINavigationController *navController = [storyboard instantiateViewControllerWithIdentifier:#"navigationController"];
UIViewController *subVC = [storyboard instantiateViewControllerWithIdentifier:#"subVC"];
[navController pushViewController:subVC animated:NO];
[self.navigationController presentViewController:vc animated:YES completion:nil];

Related

Push navigation from current context

Hi i have two Viewcontroller A and B and i am presenting B Controller from A Controller with Current Context and I pasted my coding below. All i want to push from B controller to C controller, I know that no navigation controller allocated when we present and if i present navigationcontroller with rootviewcontroller i cannot achieve transparent result.
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
ChooseAddressVc *sec=[story instantiateViewControllerWithIdentifier:#"ChooseAddressVc"];
sec.myDelegate = self;
sec.modalPresentationStyle = UIModalPresentationOverCurrentContext;
sec.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:sec animated:YES completion:^{
}];
Pushing from Viewcontroller B to C
UIStoryboard*Story=[UIStoryboard storyboardWithName:#"Main2" bundle:nil];
AddNewAddressVc*choose=[Story instantiateViewControllerWithIdentifier:#"AddNewAddressVc"];
[self.navigationController pushViewController:choose animated:YES];
Note:I need to push from B to C controller when i present with current context. FOR BETTER UNDERSTANDING:WE CANNOT ALLOCATE NAVIGATION CONTROLLER AS ROOT VIEWCONTROLLER FOR A WHEN WE NEED TO GET TRANSPARENCY EFFECT
In your case self.navigationController in B view controller is nil. You need to create UINavigationController with B view controller as rootViewController. Present created UINavigationController from A instead presenting B view controller, after this you're able to use self.navigationController in B view controller.
Your code edited:
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
ChooseAddressVc *sec=[story instantiateViewControllerWithIdentifier:#"ChooseAddressVc"];
sec.myDelegate = self;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:sec];
navController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:navController animated:YES completion:^{
}];

Unable to present a view controller from AppDelegate

I need to present a view controller from app delegate.
When a phone notification comes in, I am able to decide which one of 3 view controllers (named ForumViewController, BlogViewController & NewsViewController) should be presented by analyzing the 'userInfo' in the method 'didReceiveRemoteNotification'.
But when i try to present the appropriate view controller using storyboards or the code below:
self.viewController = [[MembersViewController alloc] initWithNibName:#"MembersViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
Then, the app gives the error 'Warning: Attempt to present whose view is not in the window hierarchy!'. Also it gets stuck on a particular view controller.
Please keep in mind that the view controllers that I am trying to present are not part of the flow when the app starts (the flow is LogoViewController -> SplashViewController -> HomeViewController).
The HomeViewController & MembersViewController are essentially the main menu pages for public & private viewing. Here I have to display something to the viewer.
choice-1
using push
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
MembersViewController *vc = [navController.storyboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[navController pushViewController:vc animated:YES];
using present
MembersViewController *root = (MembersViewController *)self.window.rootViewController;
UIViewController *vc = [root.storyboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[root presentViewController:vc animated:YES completion:NULL];
upadted
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MembersViewController* pvc = [mainstoryboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[self.window.rootViewController presentViewController:pvc animated:YES completion:NULL];
Loading a view controller from the storyboard:
[self performSelector: #selector(ShowModalViewController) withObject: nil afterDelay: 0];
-(void)ShowModalViewController{
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"IDENTIFIER_OF_YOUR_VIEWCONTROLLER"];
[self.window.rootViewController presentViewController:vc animated:YES completion:nil];
}
Identifier of your view controller is either equal to the class name of your view controller, or a Storyboard ID that you can assign in the identity inspector of your storyboard.

PushViewController in fullscreen

I'd like to know if it's possible to push a ViewController of the NavigationController in full screen without tabbar and navigation bar. My problem is as follow:
My app has a NavigationController embedded in a TabBarController. In the NavController I show a FirstVC with a button to navigate to another VC. Right now I do a modal presentation to show the SecondVC. But in this SecondVC I have a tableview where a button returns a ThirdVC. This ThirdVC needs to have the navigationbar and tabbar of the FirstVC. Maybe I need to show the SecondVC with a push on the NavigationController of the first but it seems that I can't reproduce my full screen animation ...
To make it simple:
FirstVC ===> SecondVC (modal presentation) ====> ThirdVC (modal presentation):
This is my app at this time without navbar or tabbar on the ThirdVC.
Thanks in advance.
Edit
The modal presentation to the SecondVC is like that:
- (IBAction)detailButtonClicked:(id)sender {
SecondVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondVC"];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:vc animated:YES completion:nil];
}
From the SecondVC to the ThirdVC I use again presentViewController because I can't use pushViewController in modal. The result is predictable: I don't have a navigation bar or a tabbar.
I tried different things like the one below or addChildView as subview to my FirstVC:
- (IBAction)detailButtonClicked:(id)sender {
SecondVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondVC"];
UINavigationController *childNavigationController = [[UINavigationController alloc] initWithRootViewController:vc];
childNavigationController.navigationBarHidden = YES;
[self.navigationController presentViewController:childNavigationController animated:YES completion:nil];
}
and in the SecondVC
- (IBAction)changeButtonClicked:(id)sender {
ThirdVC *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"ThirdVC"];
[self.navigationController pushViewController:vc animated:YES];
}
I can't access my tabbar or navigation bar in the ThirdVC either...
What I do in your is I added following code improvement.
- (IBAction)buttonClicked:(id)sender {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
SecondViewController *vc = (SecondViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"SecondVC"];
vc.delegate = self;
[[APP_DELEGATE window] addSubview:vc.view];
[self addChildViewController:vc];
}
Main line of code is addchildViewController.
Here You can download the sample code of yours.

self.navigationController is 'null' even after embed in a navigationcontroller

I want to add a navigationcontroller to an existing viewcontroller which is created using storyboard, i have embed it in a navigation controller, but the code for navigating (shown below) is not working even after embed in the navigation controller:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
EditProfileViewController *nextViewController = [storyboard instantiateViewControllerWithIdentifier:#"EPVController"];
[self.navigationController pushViewController:nextViewController animated:YES];
When i have tried to log self.navigationController, it shows null.
Update: It is fine when i am trying with presentViewcontroller , but i
want to push the viewcontroller with navigationController.
I am struggling with this for two days,Please help.
If self is a subclass of UINavigationController, you do not need to refer to the navigationController property. (Note that this won't work if EditProfileViewController is also a subclass of UINavigationController, as you can't push a UINavigationController inside a UINavigationController).
EditProfileViewController *nextViewController = [storyboard instantiateViewControllerWithIdentifier:#"EPVController"];
[self pushViewController:nextViewController animated:YES];
Otherwise, if you don't have a pre-existing navigation controller
EditProfileViewController *nextViewController = [storyboard instantiateViewControllerWithIdentifier:#"EPVController"];
[self presentViewController:nextViewController animated:YES completion:nil];

Need to return to the presenting UIViewController from within a presented UINavigationController

In MyMainViewController, I present a navigation controller like this:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UINavigationController* nc = [storyboard instantiateViewControllerWithIdentifier:#"NAVIGATION_CONTROLLER_ID"];
[self presentViewController:nc animated:YES completion:nil];
Later, from somewhere within the view hierarchy of the UINavigationController, I need to return to MyMainViewController. How can I do this?
(Note: MyMainViewController is defined in a .XIB, and not in the storyboard where the UINavigationController and it's children are defined.)
It sounds like you have modally presented a NavController that you want to remove. Modally presented VC's can remove themselves.
Somewhere in your NavController add:
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Dismissed nav controller modally");
}]
[self.navigationController popToViewController:[[self.navigationController viewControllers] objectAtIndex:2] animated:YES];
I gues you know the index of your view controller. If you simply want to return to the rootViewController you can do it like
[self.navigationController popToRootViewControllerAnimated:YES];
If you want to push new viewController to the navigation stack just do it like
MyMainViewController *mainController = [[MyMainViewController alloc] initWithNibName:#"MyMainViewController" bundle:nil];
[self.navigationController pushViewController:desController animated:YES];
Returning to the previous viewController would be
[self dismissViewControllerAnimated:YES completion:nil];

Resources