IBOutlet is nil, but it is connected in storyboard

2020-01-23 16:50发布

Using Swift 1.1 and Xcode 6.2.

I have a UIStoryboard containing a singular, custom UIViewController subclass. On it, I have an @IBOutlet connection of type UIView from that controller to a UIView subclass on the storyboard. I also have similar outlets for subviews of that view. See figure A.

But at run time, these properties are nil (Figure B). Even though I have assured I've connected the outlets in Interface Builder.

Thoughts:

  • Is it possible that because I am using a subclass of a subclass something messes up with the initialization? I am not overriding any initializers
  • awakeFromNib: is not getting called for some reason
  • Maybe it doesn't connecting to subviews on subviews

Things I have tried:

  • Matching @IBOutlet and storyboard item types exactly (instead of UIView)
  • Deleting property and outlet and re-added them

Figure A

Figure A*

Figure B

Figure B

*The obscured code in Figure A is:

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

Thank you.

30条回答
ゆ 、 Hurt°
2楼-- · 2020-01-23 17:38

100% Working solution for creating ViewControllers from XIB without StoryBoards

  1. Create class CustomViewController : UIViewController
  2. Create view CustomViewControllerView.xib
  3. In CustomViewControllerView.xib in Interface Builder select Placeholders -> File's Owner
  4. In "Attributes inspector" set Class to CustomViewController
  5. In "Connections inspector" connect "view" to top-level view of xib (ensure top-level view's Class is not pointing to CustomViewController)
  6. In "Connections inspector" connect other outlets (if needed/exist)
  7. Create an instance of CustomViewController in parent view controller/App 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")
查看更多
我命由我不由天
3楼-- · 2020-01-23 17:39

You need to load the view hierarchy first in order to instantiate the outlets in the storyboard. For this, you can manually call the loadView or loadViewIfNeeded methods.

查看更多
欢心
4楼-- · 2020-01-23 17:41

Check your IBOutlet connection if it connected to the File owner or the view. There could be mistakes.

查看更多
干净又极端
5楼-- · 2020-01-23 17:43

Did you instantiate your view controller from a Storyboard or NIB, or did you instantiate it directly via an initializer?

If you instantiated your class directly with the initializer, the outlets won't be connected. Interface Builder creates customized instances of your classes and encodes those instances into NIBs and Storyboards for repeated decoding, it doesn't define the classes themselves. If this was your problem, you just need to change the code where you create your controller to instead use the methods on UIStoryboard, or UINib.

查看更多
Animai°情兽
6楼-- · 2020-01-23 17:43

For me, this occurred when I accidentally declared my view controller's class as

class XYZViewController: UINavigationController {
}

(ie as a UINavigationController not a UIViewController).

Xcode doesn't pick up on this mistake, the class seems to build fine, and override functions such as viewDidLoad, viewWillAppear, etc. all work correctly. But none of the IBOutlets get connected.

Changing the declaration to

class XYZViewController: UIViewController {
}

fixed it completely.

查看更多
地球回转人心会变
7楼-- · 2020-01-23 17:45

The storyboard wasn't recognizing any further UI things I added to it. At run time all the references were nil. So I cleared my derived data folder and then those connections worked again.

查看更多
登录 后发表回答