Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS >> prepareForSegue >> IBOutlet Update Doesn't Work?

I'm trying to update a Label in the 2nd VC from the 1st VC within the prepareForSegue method.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    MYSecondViewController* secondVC = (MYSecondViewController*)segue.destinationViewController;
    secondVC.titleLabel.text = @"First VC Says: You Are Second!!"; //This doesn't work
    secondVC.dataPassString = @"First VC Says: You Are Second!!"; //This works + secondVC viewDidLoad
}

If I update the Label directly, it doesn't work. If I update a String Property and then assign it to the Label in the Second VC viewDidLoad, it does work.

Does it mean that upon prepareForSegue call the second VC viewDidLoad method was not called yet?

Was some init method called (so the NSString object could pass)? If yes, which one?

Is there a way to update IBOutlets in the 2nd VC from the 1st VC?

like image 789
Ohad Regev Avatar asked Dec 23 '13 13:12

Ohad Regev


2 Answers

The short answer is: Don't do that.

You should treat another view controller's views as private and never try to manipulate them. It breaks the OOD principle of encapsulation.

What you want to do is to add (string or other type) properties to your destination view controller, and set THOSE in prepareForSegue. Then in your destination view controller's viewWillAppear method, copy those property values into the view controllers' views.

In your case, the datePassString property is exactly what you want.

That way, if you change the structure of your second view controller down the road, and decide to display the information to a different view, you don't break the link between the 2 view controllers. Your destination view controller can still fetch the data from it's source, and do something different with it.

P.S. as the other poster said, the reason setting secondVC.titleLabel.text fails is that in prepareForSegue, the destination view controller's views haven't been loaded yet.

like image 100
Duncan C Avatar answered Sep 22 '22 01:09

Duncan C


If you add in this line in your "prepareForSegue" method:

if(!secondVC.titleLabel)
    NSLog(@"titleLabel is null and it likely hasn't been loaded yet")

You'll see that the view hasn't been loaded until it's time for it to appear (which happens after prepareForSegue). That's why the datePassString property you're using is working while the IBOutlets are null until the view is loaded.

like image 34
Michael Dautermann Avatar answered Sep 21 '22 01:09

Michael Dautermann