Search code examples
iosobjective-ccocoa-touchivar

Pass data to segue destination without iVar


Since switching to storyboards, I load a view controller via

[self performSegueWithIdentifier:@"identifier" sender:self]

This works perfectly. Now, if I want to set any properties on the destination view controllers, I implement the method prepareForSegue:sender: and set what properties I need to set. Everything works as expected without any problems.

Ever since I starting using this approach over the old

MyViewController *vc = ....
vc.prop = @"value";
[self.navigationController pushViewController:vc];

I've felt that passing parameters to the destination view controller is a little hacky, in particular if the value you're trying to set is not just a static value.

Lets say for example, I have a button which fetches some data from a server. When the data returns, it creates a new object, and then presents a new view controller to display this object. To do this, I call performSegueWithIdentifier:sender:, but that's the end of it. My object is now deallocated and no longer exists, and I have no way of passing it to the prepareForSegue:sender: method, unless I store it in an instance variable.

This feels pretty horrible, as the object isn't meant to last longer than this action, and has no relation to anything else in my current view controller.

In this situation, I understand that I could quite simply request the data in the new view controller but it's just an example.

My question is, is there another way of doing this without it feeling so hacky? Can I get this data into the destination view controller without storing it in an instance variable?

I know I could still use the old approach, but I'd like to stick with the storyboard methods if I can.


Solution

  • Well the sender parameter of the performSegueWithIdentifier:sender is the same one received by the prepareForSegue:sender. So if you want to send a variable to your prepareForSegue:sender the sender is your friend. In your case:

    SomeViewController.m

    -(void)aMethodThatDownloadsSomeDataFromServer {
       NSString *exampleData = [self someDataThatIDownloaded];
       [self performSegueWithIdentifier:@"yourSegueIdentifier" sender:exampleData];
    }
    
    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
       if(segue.identifier isEqualToString:@"yourSegueIdentifier"]) { 
          if([sender isKindOfClass:[NSString class]]) { //maybe you want to send different objects
            segue.destinationViewController.stringProperty = sender;
          }
          else { 
            segue.destinationViewController.objectPorperty = sender;
          }
       }
    }