Loading Uiviewcontroller from Instantiateviewcontrollerwithidentifier - Nil Outlets

Loading UIViewController from instantiateViewControllerWithIdentifier - nil outlets

The outlets aren't set up initially. The standard way to deal with this is to store your data in properties and then move that data into your outlets in viewDidLoad.

Since you are loading this in a Singleton, viewDidLoad will only be called once. Instead, copy your data from your properties to your outlets in viewWillAppear.

IBOutlet is nil, but it is connected in storyboard, Swift

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.

storyboard instantiateViewControllerWithIdentifier not setting IBOutlets

The view seems to be initialized properly only after it is accessed first. The problem goes away when calling

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

or more simply

[vc view];

Swift/iOS: IBOutlet nil after loading view controller

The problem is the reference to InfoViewController(), which instantiates the view controller independent of any storyboard scene. You want to use instantiateViewController:

let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController
infoViewController.modalPresentationStyle = .overCurrentContext
present(infoViewController, animated: true) {
infoViewController.displayInfo()
}

A couple of notes:

  • This assumes that (a) you've given the scene in the storyboard a "storyboard id"; (b) you've set the base class for that scene to InfoViewController.

  • Note, I called displayInfo in the completion handler of present because you probably don't want that called until the scene has been presented and the outlets have been hooked up.


Alternatively, you can update non-outlet properties of the InfoViewController immediately after instantiating it and then have its viewDidLoad take those properties and update the outlets, e.g.:

class InfoViewController: UIViewController {
var info: String!
@IBOutlet weak var infoLabel: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
infoLabel.attributedText = NSAttributedString(string: info)
}
}

Note, I changed the @IBOutlet name to be infoLabel and added the String property called info. That tends to be the convention, that outlets bear some suffix indicating the type of control, and model objects, like the String property, are without the suffix. (You'll just want to make sure you remove that old outlet in the connections inspector in IB so that you don't have problems with these property name changes.)

Anyway, you can then do:

let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController
infoViewController.info = "abc"
infoViewController.modalPresentationStyle = .overCurrentContext
present(infoViewController, animated: true, completion: nil)

The key point is don't try to update outlets of the scene immediately after instantiating it, but make sure that this is deferred until after viewDidLoad was called.

IBOutlet nil after instantiateViewControllerWithIdentifier

Thanks to rdelmar, I was able to figure this out using protocols.

Here's what I added:

  • SearchDelegate
  • SearchDelegate function runSearch()

VC1

class MainViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, SearchDelegate {  

func runSearch(searchString: String) {
loadPhotos(searchString)
}

}

VC2

protocol SearchDelegate {
func runSearch(searchString: String)
}

class SearchViewController: UIViewController, UITextFieldDelegate, UISearchBarDelegate, UICollectionViewDelegate {

@IBOutlet var searchMask: UIView!
@IBOutlet var searchField: UITextField!
@IBOutlet var searchBar: UISearchBar!

var delegate: SearchDelegate?

func searchBarSearchButtonClicked(searchBar: UISearchBar) {
delegate?.runSearch(searchBar.text)
self.dismissViewControllerAnimated(true, completion:nil)

}

IBOutlet are nil in Objective C before the view controller is presented

CustomAlertViewController *customAlertVC = [gamePlaySB instantiateViewControllerWithIdentifier:CUSTOM_ALERT_VIEW_CONTROLLER];
__unused UIView* view = customAlertVC.view; // this will load everything and call viewDidLoad
customAlertVC.property.text = @"blahblah";

This is if really want to set it from outside. But as per @D. Mika answer, this is not advisable.

IBOutlet elements come out nil when I try to set them in viewDidLoad

I've had the same problem under iOS7 on very slow devices.

Just wait for your views to be rendered in viewDidLayoutSubviews then do your changes.
Don't forget to do so just once though for viewDidLayoutSubviews is being called a lot.

var first = false

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if self.first {
//Update your views
self.first = false
}
}

You could also use view.layoutSubviews() but I recommend you not to ;)

EDIT

I did not see the problem at first sight but you are creating your view controllers from scratch! You must instantiate them using a storyboard or your IBOutlets won't be set ;)

var vc1 = storyboard?.instantiateViewControllerWithIdentifier("YourControllerStoryboardId") as! CarouselViewController

Hope this'll help!

IBOutlet References found nil when containing view controller is presented programmatically

You are not grabbing the correct storyboard instance of CurrentVC but you are creating a new one. Instead of let inRunVC = CurrentRunVC(), use

let runVC = self.storyboard?.instantiateViewController(withIdentifier: "CurrentRunVC") as! CurrentRunVC //set the identifier in the storyboard identity inspector


Related Topics



Leave a reply



Submit