How to open UINavigationController Programmatically - ios

I am trying to open a UINavigationController programmatically.
Here is my code:
UIViewController *vc = [[UIStoryboard storyboardWithName:#"Storyboard"
bundle:nil] instantiateViewControllerWithIdentifier:#"ViewControllerID"];
UINavigationController *nc = [[UINavigationController alloc]
initWithRootViewController:vc];
nc.modalTransitionStyle = UIModalPresentationNone;
[self presentViewController:nc animated:YES completion:NULL];
I keep getting the following Error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'

you are completely right, but instead presenting, just push your navigation controller.
For Ex.
UIViewController *vc = [[UIStoryboard storyboardWithName:#"Storyboard"
bundle:nil] instantiateViewControllerWithIdentifier:#"ViewControllerID"];
UINavigationController *nc = [[UINavigationController alloc]
initWithRootViewController:vc];
[self pushViewController:nc animated:YES];

You should do this:
UIViewController *viewControllrer = [[UIStoryboard storyboardWithName:#"Storyboard" bound :nil] instantiateViewControllerWithIdentifier:#"ViewControllerID" ];
UINavigationController *rootViewController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.navigationController pushViewController:rootViewController animated:YES];

The message is pretty specific. It's telling you that you can't present a navigation controller modally.

Create the navigation controller inside the view controller. Add as subview the referenced nav controller's view in another presented view controller.

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:^{
}];

How do I return back to RootView Controller from my last view controller?

I have 5 view controller and want to come back from the last view to 1st view controller
Call a function in which you have to change the app rootviewcontroller. set it as a navigationController
yourViewcontoller *viewController = [[yourViewContoller alloc] init];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:viewController];
self.window.rootViewController = navController;
If you're using storyboards, give the UINavigationController a Storyboard ID. You can then initiate it and present through the code:
UINavigationController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"<Storyboard ID>"];
[self presentViewController:vc animated:YES completion:nil];
Use this method on Animation splash screen
[self performSelector:#selector(setHidden:) withObject:nil afterDelay:2.0];
-(void) setHidden:(id)sender
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboare" bundle:nil];
YourVC* vController = (YourVC*)[Storyboard instantiateViewControllerWithIdentifier:#"storyboardId"];
UINavigationController *navcotoller=[[UINavigationController alloc]initWithRootViewController:vController];
self.window.rootViewController =navcotoller;
}
If you are using UINavigationController you could and should simply call
[self.navigationController popToRootViewControllerAnimated:YES];

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.

after call presentViewController tab bar is missing

test1 is the first view in the tarbarcontorller..
after I call presentViewController tab bar is missing
How can i solve it??
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
TestTableViewController *TestTableViewController = [storyboard instantiateViewControllerWithIdentifier:#"test1"];
TestTableViewController.memberid = memberid;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:TestTableViewController];
[self.navigationController presentViewController:navigationController animated:YES completion:nil];
You should present your TabBarController, and not the first view of your tab bar controller. It will display the first view in your tab bar controller properly.

iOS/xcode/objective-c: How to instantiate view controller after signup

After a successful sign up, I want users to go through a process where they provide photo etc. Similar code to that below worked to load the login page but code below is not working to load a separate view controller in storyboard "newuser".
Would appreciate any suggestions on how to fix.
- (void)presentNewUserInterface
{
UIViewController* rootController = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"newuser"];
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController];
self.window.rootViewController = navigation;
}
Instead of:
- (void)presentNewUserInterface
{
UIViewController* rootController = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"newuser"];
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController];
self.window.rootViewController = navigation;
}
Try:
- (void)presentNewUserInterface
{
UIViewController* rootController = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"newuser"];
UINavigationController* navigation = [[UINavigationController alloc] initWithRootViewController:rootController];
[self presentViewController:navigation animated:YES completion:nil];
}
You aren't presenting your new navigation controller in your example. Is there a particular reason why you would be trying to replace your rootViewController? That shouldn't be needed. My example should be sufficient for displaying your next flow in the user sign up process.
Two variants:
Replace window.rootViewController with your next view
controller. Do it on AppDelegate class.
Present new view controller
from current root view controller. Do it in your sign up view
controller.
The lack of the first method is no transaction animation. So second method is preferable.

Resources