Storyboard instantiateViewControllerWithIdentifier does not set IBOutlets

I am using the instantiateViewControllerWithIdentifier: storyboard, and I notice that all the IBOutlets that I connected are still zero. However, IBActions I have a wired job. The view and the controller are connected (for example, controller.view is not equal to zero), and if I show that it displays what I expect.

What am I missing?

Here is my setup:

  • I have a view controller defined in my storyboard. I gave it an identifier, which is the same identifier that I use when calling instantiateViewControllerWithIdentifier:
  • I set the owner of the view by clicking on the view controller (only with the first responder), and in the "Identification Inspector" section for the "Custom Class" parameter, specify the same name as the class to which I want to connect the view.
  • Then I open the assistant editor, and the control drags the interface elements to create IBOutlets and IBActions .
+36
ios interface-builder uistoryboard
Sep 21
source share
6 answers

It seems that the view is correctly initialized only after the first call. The problem disappears when called

 [self presentViewController:vc animated:NO completion:nil]; 

or more simply

 [vc view]; 
+64
Dec 06
source share

[Use me as a bad example]

This may not be a good idea, but it works, but it breaks the normal download, making the application unstable ^ _ ^.
I will leave an answer here if someone else wants to know if you will.




I had the same problem, however the custom component that I created did not load via presentViewController (loading in the overlay to the previous view)

You can just call

myViewController.loadView() // Swift

[myViewController loadView] // Obj-C

+5
Jun 15 '16 at 11:24
source share

Setting the framework for the instantiated ViewController instance seems to set IBOutlets.

Example:

 DemoViewController *demoVC = [[self storyboard] instantiateViewControllerWithIdentifier:@"demoVC"]; demoVC.frame = self.view.frame; //or CGRectMake(0, 0, 1015, 604); 

This will initialize the IBOutlets DemoViewController such as Label, TextField, Button, Table, etc.

Hope this helps.

+1
Jan 28 '13 at 10:41
source share

Outlets are set using key value encoding, you can put this in your subclass of the view controller:

 - (void)setValue:(id)value forKeyPath:(NSString *)keyPath { [super setValue:value forKeyPath:keyPath]; } - (void)setValue:(id)value forKey:(NSString *)key { [super setValue:value forKeyPath:key]; } 

And put a breakpoint on two super calls.

In the debugger I will try:

  • Comparing the self with the view controller, you think you are using outputs. Your storyboard may have a second view controller that you don't expect. When you said you created your owner, I thought it was strange terminology. Did you drag one of the cube objects to present your view controller in addition to the existing view?

  • Compare [self valueForKey: key] or [self valueForKeyPath: keyPath] or just [self outletName] with the passed value after the call to super. Perhaps you have a setter that does not do what you intend. I saw such an error as this happens a couple of times when people have an exit for an object with a name like firstName, and then an action with the selector "setFirstName:". This confuses the encoding of key values, and you get setFirstName: receiving a call during nib boot in order to set the exit, but the installer for the exit is implemented as an action method, so the output is never set.

0
Sep 21
source share

If the object you are referencing is a top-level object in the scene, such as an ArrayController, the link must be strong (not weak!) Because it is not preserved by the view hierarchy. A weak link can cause a problem, like what you are describing.

See more information: Should IBOutlets be strong or weak in ARC?

0
May 26 '16 at 18:35
source share

People have given a decision on how to load the view (some of which you should never use ( loadView() ), so here you can check if your view is loaded

I ran into a problem because I had a property with the didSet observer to update the user interface, which obviously does not work if the outputs are not already set, here is an example code to get around it:

 var name: String? { didSet { updateNameLabel() } } override func viewDidLoad() { super.viewDidLoad() updateNameLabel() } func updateRoomLabel() { guard isViewLoaded() else { return } [...] } 

So, now that you show that the sockets are updated, but also every time you update a property

0
Sep 26 '16 at 15:05
source share



All Articles