2

I perform a segue which is defined in the Storyboard to open a new view controller. I need to configure the destination view controller of the segue in a special state where some of it's buttons does not needed to be displayed.

I know that I can do this by setting a variable on this controller in my source view controller's -prepareForSegue:sender:. The problem with this is, that firstly it instantiates the controller, so it's -viewDidLoad: will run, then only after can I set anything on it.

I can't create the controller entirely from code, because it's user interface is in Storyboard. -instantiateViewControllerWithIdentifier: also calls -viewDidLoad first obviously.

I could probably use a semaphore and add the initialization code into my destination controller's -viewWillAppear, but that's ugly, it has to be some more elegant way to do this than doing a check every time the view appears. (My settings need to be done only once.)

Is there some way to pass variables into the controller before it's -viewDidLoad runs?

EDIT: It looks like this happens only if I trigger the segue from code using -performSegueWithIdentifier:.

gklka
  • 2,459
  • 1
  • 26
  • 53
  • Why not set these buttons to be hidden by default, then turn them on or not in viewDidLoad? You can then control what gets displayed. – Micrified Sep 17 '15 at 21:42
  • That does not change anything. Hiding or showing them needs to happen in viewDidLoad. – gklka Sep 17 '15 at 21:43
  • So your issue is that you cannot override `viewDidLoad`, rather than you asking to somehow pass and perform configurations before that method gets called. This was a bit unclear to me. My bad. – Micrified Sep 17 '15 at 21:45
  • My problem is, that I want to use viewDidLoad for setting up my view (because it needs to be done only once), and I can't do that, because I don't have the values of my variables, which I would use to set it up (they will be set after viewDidLoad). – gklka Sep 23 '15 at 21:14

2 Answers2

1

On my machine and on iOS 8.0 and iOS 9.0, viewDidLoad is called after prepareForSegue. So, something like the following worked for my test case of your answer.

In your source controller:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    TimViewController * controller = segue.destinationViewController;

    if( [controller isKindOfClass:[TimViewController class]] )
        controller.name = @"tim";
}

In your destination controller (TimViewController):

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do view setup here.

    NSLog( @"view did load %@", self.name );
}

Add a segue (a show segue) from your source control to the destination view controller.

Output:

2015-09-17 19:09:04.351 Test[51471:7984717] view did load tim
Timothy Davison
  • 429
  • 2
  • 7
  • Perhaps I misunderstood the question? – Timothy Davison Sep 18 '15 at 01:18
  • 1
    Ok, I have created a test project for this, and you are partially right. `-prepareForSegue:` definitely runs before `-viewDidLoad` but only if the segue is invoked by Storyboard. If you trigger it from code using `-performSegueWithIdentifier:`, it works differently. See my test project here: https://github.com/gklka/SegueTest – gklka Sep 23 '15 at 12:10
1

I think there is some confusion here. -prepareForSegue:sender: gets called before -viewDidLoad gets called. Please double check your implementation.

Edit:

May be this thread will help you understand this and one of the mentioned cases fall in your case.

Community
  • 1
  • 1
Abhinav
  • 37,684
  • 43
  • 191
  • 309