pass NSMutableArray from root view controller to pushed view controller - ios

i have 2 view controllers the first 1 is the root of uinavigationcontroller.
in that view controller (the first) i have nsmutable array that contains custom class that i created. so far so good :).
now in the second view controller (the child of the first) there is another nsmutable array
and i want to pass to him the array from the first view controller(from the root).
so in the method:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
i used this code:
if([segue.identifier isEqualToString:#"showDetailSegue"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
tableViewController *controller = (tableViewController *)navController.topViewController;
controller.monthnames = monthnames;
}
but when i run the program and perform the segue i got this error message:
[tableViewController topViewController]: unrecognized selector sent to instance 0x9836f20
what am I'm doing wrong?
thanks to all helpers :)

segue.destinationViewController is already your second view controller
(and not the navigation controller):
if([segue.identifier isEqualToString:#"showDetailSegue"]){
tableViewController *controller = (tableViewController *)segue.destinationViewController;
controller.monthnames = monthnames;
}

I believe your segue point to table view controller not navigation controller. Replace your code to:
if([segue.identifier isEqualToString:#"showDetailSegue"]){
tableViewController *controller = (tableViewController *)segue.destinationViewController;
controller.monthnames = monthnames;
}
It should help.

Related

Segue issue with SWRevealViewController

I'm trying to segue from side menu page of SWRevealViewController and transfer data to another view controller. It is crashing and I'm getting this issue ` -[UINavigationController setStr1:]: unrecognised selector sent to instance 0x7f8c92224c80 '
while I'm using Reveal View Controller Push Controller method to push to the other view controller.
On the other hand in other view controllers I'm using SHOW instead of SWRevealViewControllerSeguePushController and it is working fine not crashing. I'm using storyboard.
Please where would be my issue?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"TESTTEST"]) {
ViewController *destViewController = segue.destinationViewController;
destViewController.str1 = #"data pass";
}
}
The error indicates that the segue destination view controller is a navigation controller (which consequently doesn't respond to the setStr1 selector). So it looks like your ViewController is embedded in a navigation controller in the storyboard. If so, change your code as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"TESTTEST"]) {
UINavigationController *navigationController = segue.destinationViewController;
ViewController *destViewController = navigationController.topViewController;
destViewController.str1 = #"data pass";
}
}

[UITabBarController setSports:]: unrecognized selector sent to instance 0x7b80e2b0

I’m building an iOS app. I want pass array value from one view controller to another through segue.
While doing this i’m getting an error:
[UITabBarController setSports:]: unrecognized selector sent to
instance 0x7b80e2b0.
here is my code:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"sportsSelection"]) {
Play *play=[segue destinationViewController];
play.sports=selectedSports;//error break point is here.
//sports and selected sports are NSMutableArray
}
}
To make the situation a bit clearer, you are getting the error because you are trying to call a method (setSports:) on a class that does not implement this method, this is exactly what the error message tells you:
[UITabBarController setSports:]: unrecognized selector sent to
instance 0x7b80e2b0.
Your segue apparently has a UITabBarController as destination, so it's clear that it does not know about the method setSports:, since this one is actually implemented in your custom view controller (apparently called Play?!).
Then, as Eike pointed out in his answer, you need to get Play from the UITabBarController which it is embedded in. That's why he suggested to use: Play* p = ((UITabBarController*)segue.destinationViewController).viewControllers[0];, it means that you should get the view controller at index 0 from your UITabBarController.
According to your comment, the view controller at index 0 is a UINavigationController, which (naturally) also does not respond to setSports:, because just like UITabBarController it is a class provided by Apple and doesn't know about this method.
Now, you need to find out where in this UITabBarController your custom view controller Play is located. Either it is a direct part of UITabBarController and you can find it by using Eike's approach and just modify the index from 0 to n (where n is the number of view controllers that the UITabBarController has hold of), or another option is that it is embedded in the UINavigationController that you received at index 0, so in that case you'd have to access the UINavigationController's view controller stack (e.g. the array property viewControllers or just the one that is currently on top of the stack using topViewController).
Edit: I want to give you some extra information about what's going on in your code, especially related to Eike's answer:
From the information that you gave us in your question and in the commment to Eike's solution, we can assume the following code to be correct:
if ([[segue identifier] isEqualToString:#"sportsSelection"]) {
UITabBarController *tabBarController = [segue destinationViewController]; // the destination of the segue is your `UITabBarController`
UINavigationController *navigationController = tabBarController.viewControllers[0]; // gets the first of the view controllers contained in your UITabBarController
NSLog(#"view controllers in navigation controller: %#; top view controller: %#", navigationController.viewControllers, navigationController.topViewController); // print all view controllers managed by navigationController
}
EDIT 2: From your comment I can now assume the following code to be correct:
if ([[segue identifier] isEqualToString:#"sportsSelection"]) {
UITabBarController *tabBarController = [segue destinationViewController]; // the destination of the segue is your `UITabBarController`
UINavigationController *navigationController = tabBarController.viewControllers[0]; // gets the first of the view controllers contained in your UITabBarController
Play *controller = (Play *)[[navigationController viewControllers] objectAtIndex:0];
controller.sports=selectedSports;
play.sports = selectedSports;
}
You need to setSports: to your view controller not the UITabBarController.
Play* p = ((UITabBarController*)segue.destinationViewController).viewControllers[0];
p.sports = selectedSports;

Passing data between controllers gives an error due to complicated segue

I have a modal segue which goes from a view controller to a tab bar controller which is embedded in a table view as you can see from this screenshot:
I want to pass data between the login screen and the table view. I use the following code:
-(IBAction)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Enter App"]){
//Pass on username so that app can set everything up for that specific user
GamesListTableViewController *gamesList = (GamesListTableViewController *)segue.destinationViewController;
if ([segue.destinationViewController isKindOfClass:[GamesListTableViewController class]]) {
NSLog(#"ENTERING PROPER CLASS");
}
else{
NSLog(#"ENTERING WRONG CLASS");
}
gamesList.userID = self.userID;
}
}
My app crashes due to the last line of code. And i checked why (as you can see in the code above) and the reason is that the segue destination is not the GamesListTableViewController, but what i am assuming is the tab bar controller. How to i work around this problem?
UITabbarController *tabController = (UITabbarController*) segue.destinationViewController;
UINavigationController *nav = (UINavigationController*) tabController.viewControllers[0]; // or some other nr
GamesListTableViewController *tvc = nav.topViewController;

Pass String from UINavigationController to ViewController

I have three classes :
1.TyphoonViewController
2.WaterTableNaviController
3.WaterTableViewController
I am trying to pass a string from the first one to the last. But I only pass the string from the first to the second. It will be a black screen when I present the third ViewController.
I've tried to make the WaterTableViewController be the root of WaterTableNaviController in storyboard.
It did present screen, but the string wasn't passed.
From TyphoonViewController
- (IBAction)ParseBut:(id)sender {
WaterTableNaviViewController *vc = (WaterTableNaviViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"WaterTableNavi"];
[vc setUrl:#"My String"];
[self presentViewController:vc animated:YES completion:nil];
}
From WaterTableNaviController
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
WaterTableViewController* vc = (WaterTableViewController*)[self.storyboard instantiateViewControllerWithIdentifier:#"WaterTable"];
[vc setParseUrl:m_url];
[self.navigationController pushViewController:vc animated:YES];
}
The code you have in the navigation controller is wrong - if the WaterTableVC is the root view controller of the navigation controller, it's already been instantiated, so you shouldn't do it again. Also, you don't push to the root view controller. You don't need to subclass the navigation controller at all to do what you are trying to do here. You should make a modal segue from the button in TyphoonViewController to the navigation controller, and make WaterTableViewController the root view controller of that navigation controller. The button should not have any action method, because it triggers the segue directly. Instead, you should have the following code in prepareForSegue,
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UINavigationController *nav = segue.destinationViewController;
WaterTableViewController *waterTableVC = (WaterTableViewController *)nav.topViewController;
[waterTableVC setURL:#"My String"];
}
You can simply make another singleton class and put a property that can contain that string, so wherever you are, you can read that property

How do I push a view controller from a custom view action using storyboards/IB?

I have a navigation controller than manages a view with a custom component that does not show up on the storyboards/interface builder. When I trigger a particular action, I would like to push on the next view controller. I can do this in code, but I would like to stick to storyboards as much as possible. Is there a way to establish this link?
Thanks
Use prepareForSegue in your (root) view controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"SeguName"]) {
UINavigationController * navigationController = segue.destinationViewController;
PlayerDetailsViewController * playerDetailsViewController = [[navigationController viewControllers] objectAtIndex:0];
playerDetailsViewController.delegate = self;
}
}

Resources