IBOutlet is zero, but it is linked in the storyboard, Swift

Using Swift 1.1 and Xcode 6.2.

I have a UIStoryboard containing a special, UIViewController subclass of the class. I have a @IBOutlet connection of type UIView from this controller to a subclass of UIView on the storyboard. I also have similar outputs for peeping at this point. See Figure A.

But at runtime, these properties are zero (Figure B). Despite the fact that I am sure that I connected the outputs in Interface Builder.

Thoughts

  • Is it possible that since I am using a subclass of the subclass, something will go wrong with initialization? I do not override any initializers
  • awakeFromNib: not called for any reason
  • It may not connect to subviews on subviews

What I tried:

  • Matching @IBOutlet and types of storyboard elements exactly (instead of UIView )
  • Removing properties and output files and adding them again.

Figure a

Figure A *

Figure b

Figure B

* The obscure code in Figure A is:

 @IBOutlet private var annotationOptionsView: UIView! @IBOutlet private var arrivingLeavingSwitch: UISegmentedControl! 

Thank.

+94
null xcode swift uistoryboard iboutlet
Mar 28 '15 at 19:09
source share
30 answers

The storyboard did not recognize any additional user interfaces that I added to it. During operation, all links were zero. So I cleaned up the derived data folder, and then these connections worked again.

+15
Mar 29 '15 at 2:04
source share

This usually happens because your view controller has not yet loaded its view hierarchy. A view controller loads its view hierarchy only when something sends it a view message. The system does this when it is time to actually display the hierarchy of views on the screen, which happens after things like prepareForSegue:sender: and viewWillAppear: returned.

Since your VC has not yet loaded its presentation hierarchy, your outputs are still null.

You can force VC to load its view hierarchy by saying _ = self.view .

+135
Mar 28 '15 at 20:41
source share

Have you tried working with the product> Clean. Solved a very similar problem for me.

+27
Apr 6 '15 at 1:23
source share

Did you create an instance of your view controller from the storyboard or NIB, or did you create it directly through the initializer?

If you instantiated your class directly with the initializer, the outputs will not be connected. The Builder interface creates individual instances of your classes and encodes these instances in NIB and Storyboards for re-decoding; it does not define the classes themselves. If this was your problem, you just need to change the code in which you create your controller, use the methods on UIStoryboard or UINib instead.

+20
Mar 28 '15 at 21:49
source share

This happened to me with my custom collections view cell. Turns out I had to replace my registerClassforReuseIdentifier method with registerNib. This fixed it for me.

+12
Nov 26 '15 at 10:16
source share

In my case, this happened because I redefined the loadView method in my subclass of ViewController, but forgot to add [super loadView]

 -(void)loadView { // blank } 

When you override the loadView method, it is your responsibility to initialize your routines. Since you override it, the views from the interface constructor do not get the ability to convert to cocoa objects, and therefore the outputs remain null.

If you implement loadView in a subclass of the view controller, then it becomes the responsibility to load user interface elements from the / xib storyboard into the code.

Or just call

 [super loadView]; 

So the superclass will be able to load the / xib storyboard into the code.

+10
Jan 13 '17 at 9:38 on
source share

You can call controller.view to force the view to initialize IBOutlets, then you can assign values.

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if (segue.identifier == "identifier") { let controller = segue.destinationViewController as! YourController let _ = controller.view //force to load the view to initialize the IBOutlets controller.your_IBOutlet_property = xxx ... controller.delegate = self } } 
+8
Aug 08 '16 at 3:12
source share

This happened to me because I accidentally created an instance of my view controller, rather than creating it through a storyboard. If you instantiate directly through MyViewController() , then the outputs will not be connected.

+8
Oct. 15 '16 at 19:05
source share

For me, this happened when I accidentally declared my controller class of the form

 class XYZViewController: UINavigationController { } 

(i.e., as a UINavigationController not a UIViewController ).

Xcode does not catch this error, the class seems to build fine, and overrides functions like viewDidLoad , viewWillAppear , etc. all work correctly. But none of IBOutlet connects.

Change ad to

 class XYZViewController: UIViewController { } 

fully fixed.

+6
Jul 15 '16 at 14:50
source share

I recently ran into this problem! Here is my thought. The problem is not that you are a storyboard or some kind of problem with the channel. It's about how you initiate your ViewController. Especially when you use Swift. (When you create a class file, nothing happens in the editor)

Just using init() from the superclass, you cannot initiate anything that you worked with the board. So, you need to change the initialization of the ViewController. replace let XXViewController = XXViewController() from let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController This tells the program to go to the storyboard to find XXViewController and initiates all the IBOutlet in your storyboard.

We hope for this help ~ GL

+4
Nov 03 '15 at 8:29
source share

If you instantiate the view controller programmatically. then try to create it as below

 let initialVC = self.storyboard?.instantiateViewController(withIdentifier: "InitialVC") as! InitialVC 

instead of directly

 let initialVC = InitialVC() 

It worked for me.

+4
Jul 19 '18 at 6:44
source share

For Swift 3.

 func configureView() { let _ = self.view } 
+3
Apr 09 '17 at 2:36 on
source share

You must first load the view hierarchy to create instances in the storyboard. To do this, you can manually call the loadView or loadViewIfNeeded methods.

+2
May 31 '17 at 12:47 a.m.
source share

In my case, the application suddenly started to freeze. Debugging showed that all sockets were still nil during viewDidLoad() .

My application still uses feathers (not storyboards) for most view controllers. Everything was in place, all sockets were connected correctly. I double checked.

Usually we create our view controllers as

 let newVC = MYCustomViewController() 

... which for some reason seems to work as long as .xib is named the same as the view controller class (although not sure how it works. We do not call init(nibName:bundle:) with null arguments or override init() do it on self , as usually suggested ...).

So I tried to explicitly call

  let newVC = MYCustomViewController(nibName: "MYCustomViewController", bundle: .main) 

... only welcome with runtime exception error:

*** The application terminated due to an unsuccessful exception "NSInternalInconsistencyException", reason: "Failed to load the NIB bundled:" NSBundle & lt; / Users / nicolasmiari / Library / Developer / CoreSimulator / Devices / 3DA3CF21-108D-498F-9649 -C4FC9E3C1A8D data / Containers / Bundle / Application /C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.app & GT; (loaded) 'named' MYCustomViewController ''

And then I saw this:

The Target Membership checkbox in the .xib file has not been set.




This could happen if one of the common merge conflicts associated with the Xcode project file is resolved.

Apple should definitely come up with a project file format that is more SCM friendly.

+2
03 Sep '18 at 2:20
source share

100% working solution for creating ViewControllers from XIB without StoryBoards

  1. Create a CustomViewController Class: UIViewController
  2. Create CustomViewControllerView.xib View
  3. In CustomViewControllerView.xib in Interface Builder, select Placeholders → File Owner
  4. In the "Attribute Inspector" set the Class to CustomViewController
  5. In the "Connection Inspector", connect the "view" to the top-level view of the XIB (make sure that the top-level view of the Class does not point to the CustomViewController)
  6. In the "Inspector of connections" plug in other sockets (if necessary / exist)
  7. Create an instance of CustomViewController in the parent view controller / application delegate

7.1.

 // creating instance let controller = CustomViewController() 

7.2.

 // connecting view/xib with controller instance let bundle = Bundle(for: type(of: controller)) bundle.loadNibNamed("CustomViewControllerView", owner: controller, options: nil) 

7.3.

 // get/set outlets controller.labelOutlet.text = "title" controller.imageOutlet.image = UIImage(named: "image1") 
+2
Oct 17 '18 at 3:24
source share

Check the IBOutlet connection if it is associated with the file owner or view. There may be errors.

+1
May 22 '16 at 8:53 a.m.
source share

Another case:

Your outputs will not be set until the view manager view is actually created, which in your case is likely to happen shortly after initWithNibName: bundle: -at, at which point they will still be nil. Any customization you make that includes these outputs should happen in your viewviewDoadLoad controller method.

+1
Jun 03 '16 at 12:16
source share

For me, I had the same error on a localized storyboard, the item was added to some locale, and not to another, so I had a null reference for this item when switching to the missing item locale, I had to remove (redundant) for this Storyboards using https://stackoverflow.com/a/318960/

+1
May 29 '17 at 12:38 pm
source share

For me this is a failure because containerView was null.

Here is my code with Crash .

 @IBOutlet private var containerView: UIView! // Connected to Storyboard override open func loadView() { containerView.addSubview(anotherView) } 

The missing thing called super.loadView() . So adding it for me solved the problem.

Fixed Code :

 @IBOutlet private var containerView: UIView! override open func loadView() { super.loadView() containerView.addSubview(anotherView) } 
+1
Sep 25 '17 at 14:25
source share

I had a similar problem when I previously added register (_: forCellReuseIdentifier :) for the custom cell after I already defined the identifier in the storyboard. Had this code in the viewDidLoad () function. As soon as I deleted it, it worked fine.

+1
Oct 25 '17 at 18:07 on
source share

Another case that I came across. I changed the name of my class for the UIViewController, but I forgot to change the name of the .xib file where the interface was built.

As soon as I caught it and made the file names reflect the class name, everything was fine!

I hope this helps someone.

+1
Dec 05 '17 at 1:00
source share

There is one more...

If you have a custom class for UITableViewCell, but don't forget to specify Custom in cell style.

+1
Feb 13 '18 at 2:15
source share

You can check if the view is loaded.

 if isViewLoaded && view.window != nil { //self.annotationOptionsView. } 
+1
May 28 '18 at 16:13
source share
  • select .h and .m files to view controller files.
  • delete the link for these files
  • re-add files to the project tree
  • open the storyboard, eventually rebuild the project
0
10 Sept. '15 at 5:52
source share

I see that you are using ViewController !? in ViewController class should use -viewDidLoad , not use -viewDidLoad , use -viewDidLoad for the UIView class

0
Apr 25 '17 at 9:04 on
source share

Unfortunately, I have subclassed my AVPlayerViewController view controller instead of the UIViewController . Replaying it with the UIViewController , everything returns to normal. This should help.

No cleanup of the assembly (normal and complete), deleting folders with derived data and exiting Xcode for me.

0
Jul 23 '17 at 5:52 on
source share

I had the same issue after copying a class (associated with xib) to reuse it with another viewcontroller class (associated with the storyboard). I forgot to delete

 override var nibName 

and

 override var nibBundle 

methods.

After removing them, my exits began to work.

0
Aug 24 '17 at 15:17
source share

Check if you have lost or disconnected outlets.

enter image description here

0
Mar 02 '18 at 13:49
source share

If you have two main.storyboards and you make changes to the wrong one, this can happen. This can happen every time you plug in an outlet from an unexpected storyboard .

0
Jun 16 '18 at 22:21
source share

2019, ONE POSSIBILITY OF THIS AWESOME PROBLEM:

  • Let's say you have a container view that shows, say, some kind of clock. So you have

    Clock Class: UIViewController

You really use it in several places in the application. On the home screen, there is a details screen and an editing screen.

You have a sophisticated, modern application similar to Snapchat, and indeed, Clock can be downloaded more than once at a time (possibly hidden).

You start working on one use of Clock on one of your many storyboards ... you add a new L tag and, of course, add a socket, and it should work. All other outlets work fine.

But the application crashes with L as zero.

The reason is that you only have an “L” on ... one of the clock storyboard options!

The failure came from >> another place where & lt; & lt; & lt; you are using a watch. (where there is no new “L” element on the storyboard).

Disappointment.

0
Sep 03 '19 at 2:11
source share



All Articles