Pass variable to View Controller Embedded in Navigation Controller in Objective-C - ios

I have embedded a destination viewcontroller in a navigation controller and am now unable to pass it a variable.
My code is:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
//THis is the navigation controller
UIViewController *destVC = [storyboard instantiateViewControllerWithIdentifier:#"myNav"];
//This is the view controller embedded in the nav
IDNowVC* myVC = [storyboard instantiateViewControllerWithIdentifier:#"myVC"];
myVC.sender = #1;//for contacts
[self presentViewController:destVC animated:YES completion:nil];
After the launch of the VC, sender property is nil. It is not getting the value #1.
What am I missing?
Thanks for any suggestions.

In your code you have a comment that says:
//This is the view controller embedded in the nav
However, the view controller below that comment is not the one embedded in your navigation controller. It's a completely new controller that is created at that line and disposed of at the end of the function.
You need something more like this:
UINavigationController *destVC = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"myNav"];
IDNowVC* myVC = destVC.childViewControllers[0];
myVC.sender = #1;
There might be some syntax issues with the above...

Related

Objective-C Present View Controller with its Navigation Controller

I have a view controller like in the image below:
And I am trying to present this view controller from another view controller like so:
LHPDFFile *vc = [[LHPDFFile alloc] init];
vc.previewItemURL = self->_previewItemURL;
UINavigationController *navBar=[[UINavigationController alloc]initWithRootViewController:vc];
[self presentViewController:navBar animated:YES completion:nil];
This works, however my buttons are not appearing :(
It appears that the code above is creating a Navigation Controller instead of using mine with the buttons. What am I doing wrong?
Try instantiating your view controller with the storyboard. Something like:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"YourStoryboardName" bundle:nil];
LHPDFFile *vc = (LHPDFFile *)[storyboard instantiateViewControllerWithIdentifier:#"<id of your view controller in the storyboard>"];
Calling the empty init method leads to empty instantiation of the view, because you have never mentioned that it should use this storyboard's this view controller. More details here.
You init none of your controllers from storyboard! Those buttons belongs to file view controller. You should init that controller from storyboard instead of call init.
MyViewController *vc = [[self storyboard] instantiateViewControllerWithIdentifier: #"MyViewControllerStoryBoardID"];
UINavigationController *navBar = [[UINavigationController alloc]initWithRootViewController:vc];
[self presentViewController:navBar animated:YES completion:nil];

How to pass value to a viewController embedded in NavigationController

There are similar questions but they are either in swift or are not solving my problem.I've a view controller which is presenting navigation view controller when cell did select button is pressed as:
patientBillNavigationViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PatientBillVC"];
//soem value assignment
[self presentViewController:viewController animated:YES completion:nil];
You can say billing opens up a whole new view independent of the main app flow to handle billing process.
The view this navigation View Controller automatically loads is the bill view and now if I want to pass a value from this viewcontroller to the other viewController embedded in navigation view I can't do that. How to pass a value?
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
PatientBillViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"PBVC"];
vc.superBillToAddEdit = sb;
//then display the view embedded in navigation view
But this is not working.
One way I know is to Subclass UINavigationViewController and in its viewDidLoad, you can do:
YourEmbeddedVc *svc =self.viewControllers[0]; //get the controller reference
svc.name= #"Hello";
I'm assuming you are only having one controller in your navigation stack, if not you need to find out the proper match of the required VC.
I might not be understanding the question exactly, correct me if I'm wrong.
It sounds like you want to start a nav controller from a view controller (let's call this firstViewController) and pass a value from firstViewController to the view controller that will eventually load in the nav controller.
If that's the case, why don't you create the second view controller (billingStep1ViewController) and then assign the value to it as a property, then pass the billingStep1ViewController to the nav controller's initWithRootViewController: method?
Something like this (untested code, btw):
// this code would go inside our FirstViewController file
// create the first vc that will be loaded in the nav controller
BillingStep1ViewController *billingStepOneVc = [self.storyboard instantiateViewControllerWithIdentifier:#"stepOne"];
// set the value you want
billingStepOneVc.bill = myBill;
// create new nav controller with step one vc as the root
UINavigationController *uiNavController = [[UINavigationController alloc] initWithRootViewController:billingStepOneVc];
[self presentViewController:uiNavController];
That way you can have two view controllers talking directly with one another and not worry about the navigation controller at all.
Update: Here is some tested code that works to illustrate my idea:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
//create the step 1 view controller - this is the first view controller we will see in the navigation controller
StepOneViewController *stepOneVc = [storyboard instantiateViewControllerWithIdentifier:#"stepOne"];
//assign a value to it (name is an NSString #property of StepOneViewController)
stepOneVc.name = #"Jones";
//this is the nav controller we will display, we set the root vc to our step one.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:stepOneVc];
//present the nav controller on screen.
[self presentViewController:navController animated:YES completion:nil];
Some of the class names changed but the idea is the same.
Rather than creating the navigation controller from its storyboard identifier, create it programmatically, with the PatientBillViewController you created as its root view controller. Like this:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
PatientBillViewController *pbVC = [mainStoryboard instantiateViewControllerWithIdentifier:#"PBVC"];
pbVC.superBillToAddEdit = sb;
PatientBillNavigationViewController * navVC = [[PatientBillNavigationViewController alloc] initWithRootViewController:pbVC];
[self presentViewController:navVC animated:true completion:nil];
Swift Version
Here is the swift version answer for the above problem!!
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PatientBillVC") as! patientBillNavigationViewController
vc.name = "name"
let mVc = UINavigationController.init(rootViewController: vc)
self.navigationController?.present(mVc, animated: true, completion: nil)

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

properly set up navigation controller as a root for a uitab bar

I am a little bit confused and cannot make things to work.
So, this is my code in my app Delegate.
// If the device is an iPad, we make it taller.
_tabBarController = [[AKTabBarController alloc] initWithTabBarHeight:(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 70 : 50];
NSString * storyboardName = #"Main_iPhone";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
CurrentViewController * tab1VC = [storyboard instantiateViewControllerWithIdentifier:#"Tab1"];
// dummy controllers
CurrentViewController * tab2VC = [storyboard instantiateViewControllerWithIdentifier:#"Tab1"];
CurrentViewController * tab3VC = [storyboard instantiateViewControllerWithIdentifier:#"Tab1"];
CurrentViewController * tab4VC = [storyboard instantiateViewControllerWithIdentifier:#"Tab1"];
[_tabBarController setViewControllers:[NSMutableArray arrayWithObjects:
tab1VC,
tab2VC,
tab3VC,
tab4VC,
nil]];
[_window setRootViewController:_tabBarController];
[_window makeKeyAndVisible];
Then, in my storyboard I have the image below :
So, I have my ViewController and I clicked Embed In > Navigation Controller
I want to have a different navigation controller for each tab.
Inside my CurrentViewController I have this when button is clicked :
- (IBAction)dummyButton:(id)sender {
NSString * storyboardName = #"Main_iPhone";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UserSettingsSetupViewController *userSettingsSetupController = [storyboard instantiateViewControllerWithIdentifier:#"UserSettingsSetup"];
[[self navigationController] pushViewController:userSettingsSetupController animated:YES];
}
And apparently nothing is pushed into the navigation Controller because nothing opens.
Doing some research, I saw that this is because [self navigationController] or self.navigationController returns nil.
but why is that? Should I add any code? I thought that by doing that from storyboard, it shouldn't be nil? Am I wrong?
A couple of comments. First of all, if you're using a storyboard, don't create view controllers in the app delegate; drag all the controllers you need into the storyboard. There's no need for any added code in the app delegate at all.
Your problem is caused by trying to mix storyboard controllers and code in the app delegate. You are instantiating tab1VC and making that the controller in the first tab -- that controller doesn't "know" anything about the navigation controller you added in the storyboard. If you wanted to do it in code (which I don't recommend), you would need to instantiate that navigation controller instead (it will take care of instantiating its root view controller), and add that as the first item in the viewControllers array.
My advice is do it all in the storyboard. Change the class of the tab bar controller there to AKTabBarController, and set its tab bar height in its init method or viewDidLoad.

iOS: Call segue from coded UIViewController outside of Storyboard

I have a custom UIVieController class that it's not included in any StoryBoard, I need to call from this class an UIViewController that is included in a StoryBoard, I tried many ways to do this but it doesn't work, always get a NSException because when I try to instance the UIViewController of the StoryBoard and get a nil object.
I don't know why it's happening this, I really appreciate any help with this.
Thank you.
Just to clarify in this code I omitted the pushing of the view to the UINavigationController.
I tried this.
+(void)loadSocialMediaAppSegue:(AXISAppDelegate*)delegate withName:(NSString*)segueId{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
AXISWebViewViewController *axisWebView = [storyboard instantiateViewControllerWithIdentifier:segueId];
}
and this
+(void)loadSocialMediaAppSegue:(AXISAppDelegate*)delegate withName:(NSString*)segueId{
AXISWebViewViewController *axisWebView = [delegate.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:segueId];
}
Ok the first thing you need to do is to add a identifier to you view controller at Storyboard, you can do that opening the Storyboard's Identity Inspector and fill the storyboard id field.
Now you are able to call this UIViewController from any place you want like this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"the name of your storyboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"the id of your view controller"];
I hope this can help you.
Please post the code you are using to instantiate the VC from the Storyboard.
In general:
To instantiate a View Controller from StoryBoard:
MyViewController *MyVC = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"MyViewController"];
Make sure you set the Storyboard ID and Restoration ID and Class name to "MyViewController" or whatever you want to call it and use that as the parameter for instantiateViewControllerWithIdentifier:
Then if you are in a navigation controller, simply push the instantiated view controller onto the navigation stack:
[self.navigationController pushViewController:MyVC animated:YES];
or present it modally:
[self presentViewController:MyVC animated:YES completion:nil];

Resources