Segue infinite loop in prepareforsegue - ios

I have built a table view where one of the rows needs to go to a special view controller. I built an if statement into the prepareforsegue function to handle this, but I'm getting an infinite loop.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *myIndexPath = [self.tableView
indexPathForSelectedRow];
long row = [myIndexPath row];
if([_categoryTitle[row] isEqualToString:#"About"]){
NSLog(#"ABOUT");
[self performSegueWithIdentifier:#"aboutCat" sender:self];
}
else if ([[segue identifier] isEqualToString:#"ShowLocationsTableView"])
{
NSLog(#"ELSE");
LocationsTableViewController *ViewController =
[segue destinationViewController];
ViewController.categoryDetailModel = #[_categoryTitle[row],
_categoryImages[row]];
}
}
When I click on the about row, I receive no change in view and the console prints an infinite steam of "About". Any ideas how to fix this?

You must not perform a segue in prepareForSegue. That is the source of the infinite loop.
If this row is trying to perform the wrong segue, prevent it with shouldPerformSegue (and now you can do something else).

Because you have not written any code for performing the segue when aboutCat is there
else if ([[segue identifier] isEqualToString:#"aboutCat"])
{
// code for performing aboutcat
}

Related

'-[UINavigationController setLanguage:]: unrecognized selector sent to instance 0x7f8fba7df4e0'

A few hours ago this code gave me no problems, however, after updating my XCode
my XCode and removing a 3rd party framework, it is suddenly giving me the above exception. I'm extremely confused because I don't think anything's changed between then and now that could cause the problem besides updating my XCode. Can anyone see an issue?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
/*We check to make sure the segue corresponds to segue we created when a cell is selected*/
if ([[segue identifier] isEqualToString:#"show"]) {
/*Get a pointer to the selected row*/
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
/*Get a pointer to the ViewController we will segue to*/
ViewController *viewController = segue.destinationViewController;
/*Pass the dialect and code back to the ViewController*/
viewController.language = self.languages.allKeys[indexPath.row];
viewController.code = [self.languages objectForKey:viewController.language];
}
}
Specifically, the following two lines are causing the exception:
viewController.language = self.languages.allKeys[indexPath.row];
viewController.code = [self.languages objectForKey:viewController.language];
Your segue's destination controller is a UINavigationController, your view controller is likely the top view controller of that navigation controller. You probably want:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
/*We check to make sure the segue corresponds to segue we created when a cell is selected*/
if ([[segue identifier] isEqualToString:#"show"]) {
/*Get a pointer to the selected row*/
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *navController = segue.destinationViewController
/*Get a pointer to the ViewController we will segue to*/
ViewController *viewController = navController.topViewController;
/*Pass the dialect and code back to the ViewController*/
viewController.language = self.languages.allKeys[indexPath.row];
viewController.code = [self.languages objectForKey:viewController.language];
}
}

Segue to same view Controller loads before prepareforsegue is called

Hi guys i am a beginner on Obj c Programming, I have created a "self segue"(segue to same view controller) from a tableviewcell. Now my problem is, i am setting few parameters in the prepareForSegue method, but somehow the segue already happens before this method is called(i am not even calling "performSeguewithIdentifier"). I understand that this might be because the segue is associated with the cell. But i found no other way to create a "self-segue"
please help.Btw i am using xcode6..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selctdObj = [avObjArray objectAtIndex:indexPath.row];
if([_selctdObj isContainer])
{
[self performSegueWithIdentifier:#"isContainerSegue" sender:self];
}
else
{
[self performSegueWithIdentifier:#"isItemSegue" sender:self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"isContainerSegue"]) {
// Get destination view
serverBrowseVC *sbvc = [segue destinationViewController];
[sbvc setServerSelected:_serverSelected];
[sbvc setBrowseObjID:_selctdObj];
}
}
Now invariably "isContainerSegue" gets executed ,even is the object is not a container. i also tried commenting the
//[self performSegueWithIdentifier:#"isContainerSegue" sender:self];
But every time "isContainerSegue" gets executed..
You said you weren't calling performSegueWithIdentifier, but you are. You shouldn't be if you've connected the segue from the cell. You also shouldn't implement didSelectRowAtIndexPath at all, just prepareForSegue. You can get the indexPath from the sender argument (the sender will be the cell) of prepareForSegue:sender:. If you're having a problem with the "if [_selctdObj isContainer]" clause, you need to post what isContainer does.

UIViewController not passing data between views

I'm trying to pass some data between UIViewControllers in a storyboard. I have some code below to pass the data. Whne I log the string that i'm saving on the original screen it's fine, but when I go to the UIDetailViewController the go is returning (null). What's my issue??
Original View Controller:
-(void)tableView:(UITableView *) tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView==_countryTableView) {
if (indexPath.section==0) {
AthleteDataTransfer *dataTransfer = [[AthleteDataTransfer alloc] init];
dataTransfer.name=#"Yo";
dataTransfer.dob=#"01/01/2000";
dataTransfer.description=#"I am awesome";
dataTransfer.hometown=#"Launy";
NSLog(#"%#", dataTransfer.name);
[self performSegueWithIdentifier:#"showDetail" sender:self];
}
}
}
Detail View Controller:
AthleteDataTransfer *dataTransfer = [[AthleteDataTransfer alloc] init];
_name.text=dataTransfer.name;
dataTransfer.dob=_dob.text;
dataTransfer.description=_description.text;
dataTransfer.hometown=_hometown.text;
NSLog(#"%#", dataTransfer.name);
Insted of passing data in tableViews didSelectRowAtIndexPath, pass the data in prepareForSegue method.
Like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showDetail"]) {
AthleteDataTransfer *dataTransfer = (AthleteDataTransfer *)[segue destinationViewController];
dataTransfer.name=#"Yo";
dataTransfer.dob=#"01/01/2000";
dataTransfer.description=#"I am awesome";
dataTransfer.hometown=#"Launy";
}
}
You should use prepareForSegue method to accomplish this.
and if you have more than one segues from this ViewController you can use segue.Identifier to distinguish
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if(segue.identifier==#"yoursegueidentitifer")
{
DetailedViewController *detailController = [segue destinationViewController];
detailController.nameoftextview.text =self.textViewName.text;
}
}
As suggested in other answers out here you should pass data in the prepareForSegue method. I'am not going to repeat the same code here. I wanted point out one thing that you dont want to create the DetailViewController again in the detailViewController like below
AthleteDataTransfer *dataTransfer = [[AthleteDataTransfer alloc] init]; // This is wrong and not required at all
NSLog(#"%#", dataTransfer.name);
Instead you should use self to refer the current controller
NSLog(#"%#", self.name); // This would be enough
For posting the text data to your destination View Controller, you can use the prepareForSegue method like this.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DestinationViewController *destController = [segue destinationViewController];
destController._yourTextView.text == _yourText.text;
}
}
Here, DesctinationViewController is the controller to which you want to pass the values and in the next step, you assign the values by using its object and the properties declared on that controller.
Since you are using performSegueWithIdentifier, this will automatically call prepareForSegue after performSegueWithIdentifier is executed which will show up your destination View Controller.

Segue won't change screens when clicked

I am trying to create an app with multiple scenes the first two scenes connect and transition fine using a segue, but when i add a third scene and connect it with a segue nothing happens when i click the control to transition. Here is the code i have so far
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:#"showStops"]){
NSIndexPath *indexPath = [self.directionTableView indexPathForSelectedRow];
StopsViewController *destViewController = (StopsViewController *)segue.destinationViewController;
destViewController.routeNumber =[[feeds
objectAtIndex:indexPath.row]objectForKey:#"rtNumber" ];
destViewController.direction =[[feeds objectAtIndex:indexPath.row]objectForKey:#"Direction"];
}
}
So let me see if I got it. U have a screen that connect to two others screens right? So u need two Segues with differents identifier. Than in method prepareForSegue u will check wich one was clicked.
Something like this!
- (IBAction)firstConnection:(UIButton *)sender {
[self performSegueWithIdentifier:#"firstSegue" sender:nil];
}
- (IBAction)secondConnection:(UIButton *)sender {
[self performSegueWithIdentifier:#"secondSegue" sender:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"firstSegue"]){
// YOUR TRANSITION
}
if([segue.identifier isEqualToString:#"secondSegue"]){
// YOUR TRANSITION
}
}

Unwind works properly until I add a prepareForSegue

I need help with this app I am building. If you need to see the full code, I can post it, but here is the scenario:
I have 3 UIViewControllers, SMPViewController, SMPLetterViewController and SMPDetailsViewController.
In SMPViewController I have a prepareForSegue, and an UnWind:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
SMPLetterViewController *destination = [segue destinationViewController];
destination.lblSectionText = _lblForSectionTitles;
}
-(IBAction)returnToMain:(UIStoryboardSegue *)segue{
//just return to Home page
}
In SMPLetterViewController I have a prepareForSegue, an UnWind and a button titled, “Back” that connects with the UnWind of the SMPViewController:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
SMPDetailsViewController *destination = [segue destinationViewController];
destination.lblTextLetter = _lblWordSort;
}
-(IBAction)returnToLetterList:(UIStoryboardSegue *)segue{
//just return to Letter page
}
In the SMPDetailsViewController, I have a button titled, “Home” which connects the UnWind of the SMPViewController, and a button titled, “Back” which connects with the UnWind of the SMPLetterViewController.
When I run the program everything is working properly except the Back button on the SMPLetterViewController, it keeps crashing my App. with an error telling me something is wrong with the lblTextLetter in the prepareForSegue in the SMPLetterViewController. When I comment out the prepareForSegue in the SMPLetterViewController everything works great, except I cannot transfer the information to the SMPDetailsViewController.
To me the prepareForSegue’s in both the SMPViewController and SMPLetterViewController syntax is correct so why does it not work and why is it singling out the lblTextLetter?
Any ideas as to what is wrong? Do I just need another pair of eyes as I am missing something?
Thanks for any help,
socamorti
In storyboard add segue identifier and change your prepareForSegue to something like that:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"YOUR_IDENTIFIER"]) {
SMPDetailsViewController *destination = [segue destinationViewController];
destination.lblTextLetter = _lblWordSort;
}
}
And do something like that for your second prepareForSegue as well.
This issue happens because when you run unwind action the prepareForSegue is called as well.

Resources