Iboutlet of Another View Controller Is Nil

IBOutlet of another view controller is nil

IBOutlets are initialized during view loading process and they are not accessible at the point you are trying to reach them. Instead you must declare a string variable to your viewcontroller and set text to label on its viewDidLoad method (after the loading process has finished)

class StoryViewController: UIViewController {
@IBOutlet weak var textLabel: UILabel!
@IBOutlet weak var inspiredButton: UIButton!
var text:String!

override func viewDidLoad() {
super.viewDidLoad()

textLabel.text = text
}
}

And from first controller initialize text variable as follow

let storyboard = UIStoryboard(name: "YourStoryboardName", bundle: nil)
var story = storyboard.instantiateViewControllerWithIdentifier("YourVCIdentifier") as StoryViewController
story.text = sampleText()
self.presentViewController(story, animated: false , completion: nil)

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

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 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.

iOS Swift: nil IBOutlets with custom ViewController

You have to instantiate through UIStoryboard object, something like this:

if let viewController = UIStoryboard.init(name: "YourStoryBoardName", bundle: nil).instantiateViewController(withIdentifier: "YourViewController") {
// do something with it
}

You can cast it to your custom class in at the same time of the unwrap (with as? CustomClassViewCotroller)

Edit: static func to instantiate your view controller like init:

class YourViewController: UIViewController {

static func instantiate(withViewModel vm: ViewModel) -> YourViewController? {
if let viewController = UIStoryboard.init(name: "YourStoryboard", bundle: nil).instantiateViewController(withIdentifier: "YourViewController") as? YourViewController {
viewController.viewModel = vm

return viewController
}

return nil
}

var viewModel: ViewModel?

// ...

}

There will be more optional unwrapping in your code when using viewModel var but I think this is the correct way to create view controllers programmatically (in segues you have to set variables too, but that is another history).

Good luck mate.

Changing Root view controllers gives IBOutlet as nil

I suppose you just want to show PostalViewController if user is logged. If user isn't logged you want to show just HomePageViewController. First delete these lines from app delegate, you don't need this:

window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = MainNavigationController()

Now delete the whole navigation controller class. You won't need it because you will do all of this in HomePageViewController. Now in HomePageViewController swift file add this to viewDidLoad()

isLogin = UserDefaults.standard.bool(forKey: "isLogin")
print("IsLogin --->", isLogin!)

if isLogin != nil {
performSegue(withIdentifier: "segueToPostal", sender: self)
}

In the end set segue from HomePageViewController to PostalViewController

Sample Image
Sample Image

and set its identifier as segueToPostal

Sample Image

If you don't want to let user navigate back from Postal view controller you can just embbed PostalViewController in new NavigationController. Then just set segue from HomePageViewController to this NavigationController and set identifier.

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.



Related Topics



Leave a reply



Submit