brianSan
brianSan

Reputation: 535

Objective-C (iOS): prepareForSegue won't pass my data into destination VC

VC1 = NewGameViewController
VC2 = GameViewController

NewGameViewController.m

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:@"newGameSegue"]) {
    GameViewController *gameVC = (GameViewController *)segue.destinationViewController;

    NSArray *array = [self nameArrayForTextFieldArray:self.namePicker.textFieldArray withColon:YES];
    gameVC.nameArray = [[NSArray alloc] initWithArray:array];
}

-(NSArray *)nameArrayForTextFieldArray:(NSArray *)array withColon:(BOOL *)bool basically returns an nsarray of strings given an nsarray of textfields. withcolon is a bool of whether or not you want the strings to have a colon appended to the end.

when i debug my code, the _nameArray ivar in gameVC still reads nil after every line here is called...can anyone help me out here??

Upvotes: 0

Views: 5314

Answers (3)

andreapavan
andreapavan

Reputation: 697

The prepareForSegue method is invoked by UIKit when a segue from one screen to another is about to be performed. It allows us to give data to the new view controller before it will be displayed. Usually you’ll do that by setting its properties.

The new view controller can be found in segue.destinationViewController. If GameViewController embed the navigation controller, the new view controller will not be GameViewController but the navigation controller that embeds it. To get the GameViewController object, we can look at the navigation controller’s topViewController property. This property refers to the screen that is currently active inside the navigation controller.

To send an object to the new view controller you can use this solution using performSegueWithIdentifier:

For example, if we want to perform a segue pressing a UIButton we can do this:

In the MyViewController.h we create a IBAction (connected to UIButton), dragging the button from storyboard to code:

- (IBAction)sendData:(id)sender;

In MyViewController.m we implement the method:

- (IBAction)sendData:(id)sender
{
    NSArray *array = [self nameArrayForTextFieldArray:self.namePicker.textFieldArray withColon:YES];
    [self performSegueWithIdentifier:@"newGameSegue" sender:array];
}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"newGameSegue"]) {
        UINavigationController *navigationController = segue.destinationViewController;
        GameViewController *controller = (GameViewController *)navigationController.topViewController;
        controller.nameArray = sender;
    }
}

Upvotes: 7

Rob
Rob

Reputation: 438467

I'm assuming that you've done a NSLog (or examine it in the debugger) of array immediately before setting gameVC.nameArray. You really want to make sure it's being set the way you think it is. It's amazing how many times I've spent debugging something like this only to realize the problem was in my equivalent to nameArrayForTextFieldArray. Or a typo in the name of the segue identifier. Or random things like that.

Assuming that's ok, then a couple of things are possible:

  1. How is your nameArray property defined in GameViewController? If it's not a strong reference (or a copy), then when your array falls out of scope, it will be deallocated. I think this would manifest itself slightly differently, but it's worth confirming.

  2. Also, I've seen situations where a controller like GameViewController might have some confusion between various ivars and properties (which is why I never define ivars for my properties ... I let @synthesize do that).

  3. I assume you're not using a custom setter for nameArray. I just want to make sure. If so, though, please share that, too.

Bottom line, can you show us all references to nameArray in your @interface of GameViewController as well as in its @synthesize statement?

Upvotes: 0

Scott Berrevoets
Scott Berrevoets

Reputation: 16946

Is GameViewController embedded in a navigation controller? In that case, your destinationViewController property is of type UINavigationController, not GameViewController. You can get to GameViewController by calling [segue.destinationViewController.viewControllers lastObject].

Upvotes: 0

Related Questions