I am trying to access an Array variable in a view controller in an application that is using storyboards.
BACKGROUND:
I have been following along with the Ray Wenderlich tutorial on Storyboards.
Once I finished the tutorial, I went back tried a different route, though I’m having trouble accessing a view controller. Everything is pretty much the same except my set up is the initial Scene is a View Controller. I am to the part where the author is adding some data to NSMutableArray in his table.
THEIR CODE THAT I AM USING AS A GUIDE
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = [tabBarController viewControllers][0];
PlayersViewController *playersViewController = [navigationController viewControllers][0];
playersViewController.players = _players;
I was hoping it would be a simple as replicating what I had seen with view controllers, passing along the appropriate type, but no.
I have View Controller > View Controller > Navigation View Controller > UITableViewController.
MY CODE:
UIViewController *vc = (UIViewController*)self.window.rootViewController;
UIViewController vc1 = [vc viewController][0];
UINavigationController *nc = [vc1 viewController][0];
SearchViewTableViewController *svc = [nc viewControllers][0];
svc.myarray = _myarray;
I have tried multiple combinations and am getting nowhere.
There has got to be a simpler way for me to reference classes/view/scenes.
Any help?
Make sure you are importing the ViewController header file.
Make sure you have given you ViewController a Storyboard identifier.
Then something like this should work:
MyViewController *myVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"MyViewController"];
myVC.myMutableArray = [NSMutableArray new];
....
Related
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...
This really should work. This is one of the simplest things to achieve in iOS and for some reason it's just not working.
I have two view controllers in my storyboard. One is InitViewController and the other is ViewController, with a storyboard ID of Init and ViewOne respectively. I have a button on InitViewController that is running code to switch the views. The code is running properly but nothing happens despite that fact. Here is the code:
-(IBAction)NextPage:(id)sender{
ViewController *wc = [[ViewController alloc]
initWithNibName:#"ViewOne"
bundle:nil];
[self.navigationController pushViewController:wc animated:YES];
}
I imported ViewController.h, I just don't know why this isn't working.
initWithNibName: is for view controllers that you create in .xib files, not storyboards. To create a view controller from a storyboard use -[UIStoryboard instantiateViewControllerWithIdentifier:]
ViewController *wc = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewOne"];
[self.navigationController pushViewController:wc animated:YES];
You need a NavigationController - try to log self.navigationcontroller and you will see is null
In your storyboard add a UINavigationController set it as entrypoint, set InitViewController as root view controller and then you can use:
ViewController *wc = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewOne"];
[self.navigationController pushViewController:wc animated:YES];
Using:
UIViewController *vc = [[UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil] instantiateInitialViewController];
[self presentViewController:vc animated:YES completion:^{}];
But I need to set a BOOL in the initial viewController for that story board.
I have BOOL declared in the .h and an if statement is dependent on it:
if (_boolIsTrue) {
FirstView *firstView = (FirstView *)[storyboard instantiateViewControllerWithIdentifier:#"first_view"];
[self.navigationController setViewControllers:#[firstView] animated:NO];
}
else {
SecondView *secondView = (SecondView *)[storyboard instantiateViewControllerWithIdentifier:#"second_view"];
[self.navigationController setViewControllers:#[secondView] animated:NO];
}
When I try to access it with something like:
UIStoryboard *storybord = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
UIViewController *vc =[storybord instantiateInitialViewController];
vc does not give me access to the BOOL.
Not sure what it is that I am not understanding about ViewControllers and Storyboards, but I would really appreciate the help.
Thanks
EDIT AFTER SOLUTION:
Wain was exactly right!
Here's the exact working code since my gaps spanned a couple different concepts. In case it helps someone else:
UINavigationController *nav = [[UIStoryboard storyboardWithName:#“MyStoryBoard” bundle:nil] instantiateInitialViewController];
InitialLockSetupViewController *vc = nav.viewControllers.lastObject;
vc.isBoolTrue = YES;
[self presentViewController:nav animated:YES completion:^{}];
So you have to get the View Controller with the correct type in order to access the var. BUT if it's not set as the initial view controller in the storyboard you have to get it as the root (0-th) view controller on the stack. THEN you have to remember to push the nav controller NOT the view controller.
Thanks again Wain. This was a good lesson!
You're simply not understanding that the compiler needs to know the class type. Currently you're telling the compiler that the class is UIViewController and it obviously doesn't have your custom property. You need to set the class to your custom one, like:
MyViewController *vc = [storybord instantiateInitialViewController];
Also, make sure that you don't call instantiateInitialViewController more than once or you'll have multiple copies of the same class and might use the wrong one...
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.
I am beginning iOS programming and I have hit a roadblock. I have a login view controller that redirects the control(after checking user authentication,etc) to a tab controller(homescreen) using the following code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *viewController = (UITabBarController *)[storyboard instantiateViewControllerWithIdentifier:#"homescreen"];
[self presentViewController:viewController animated:YES completion:nil];
The first view controller in home screen is a navigation controller leading to Subscription View Controller (a Table View Controller). From app delegate.m, I am trying to send an array of values (chefs) which the table can use to populate itself using the following code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tabBarController = (UITabBarController *)[storyboard instantiateViewControllerWithIdentifier:#"homescreen"];
UINavigationController *navigationController = [tabBarController viewControllers][0];
SubscriptionViewController *controller = [navigationController viewControllers][0];
controller.chefs = _chefs;
However, the table shows up empty. The NSMutable array "chefs" has been populated appropriately and in the storyboard, the table cell values (UILabels,etc.) have been hooked up correctly to their counterpart values inside Content View. As a check, I NSLogged the [self.chefs count] value inside Subscription view controller:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"%d",[self.chefs count]);
return [self.chefs count];
}
However, this returned 0. I suspect, I am not broadcasting the array properly.
EDIT:
I removed the login view controller and made the Tab bar controller the root view controller. And then used this piece of code:
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UINavigationController *navigationController = [tabBarController viewControllers][0];
SubscriptionViewController *controller = [navigationController viewControllers][0];
controller.chefs = _chefs;
Now I can see the correct cells. I am not sure if the way I am redirecting the control from login view to tab bar controller is correct OR using the way I am using storyboard ID to broadcast the array is correct. Any pointers?
It sounds like your array isn't being initialized properly, when you assign it like this:
controller.chefs = _chefs;
Before doing anything with _chefs make sure it's initialized somewhere:
_chefs = [[NSArray alloc]init];
Maybe _chefs is being released? Try assigning like this
controller.chefs = [NSArray arrayWithArray:_chefs];
Also make sure the table in controller is reloaded after your assignment. Maybe implement the setter in controller like this:
-(void)setChefs:(NSArray*)chefs
{
_chefs = chefs;
[self.tableview reloadData];
}