Whenever I perform a segue to my SignUpViewController there is an error that says unexpectedly found nil when unwrapping an optional value in the view did load, here is my code.
SignUpViewController:
Here is the view controller I am performing the segue from:
SignUpViewController:
Here is the view controller I am performing the segue from:
Code Block Swift import UIKit class MainViewController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white if isLoggedIn(){ let tabBarController = TabBarViewController() viewControllers = [tabBarController] }else{ perform(#selector(showLoginController), with: nil, afterDelay: 0.01) } } fileprivate func isLoggedIn() -> Bool { return UserDefaults.standard.isLoggedIn() } @objc func showLoginController() { let loginController = LoginViewController() present(loginController, animated: true, completion: { }) } }
Seems your code causes error when you show LoginViewController, not when segue to SignUpViewController.
(You should better show on which line the error is shown, that may prevent misunderstanding.)
This line is the worst part of your code:
When you create a design of a view controller using storyboard, calling initializer init() like LoginViewController() just creates a garbage object which causes unexpectedly found nil and would never work.
Why don't you use instantiateViewController(identifier:) as you do in LoginViewController:
(Put a Storyboard ID to LoginViewController, and use it in instantiateViewController(identifier:).
I haven't checked other parts of your code. If this does not work, please tell me with detailed description.
(You should better show on which line the error is shown, that may prevent misunderstanding.)
This line is the worst part of your code:
Code Block let loginController = LoginViewController()
When you create a design of a view controller using storyboard, calling initializer init() like LoginViewController() just creates a garbage object which causes unexpectedly found nil and would never work.
Why don't you use instantiateViewController(identifier:) as you do in LoginViewController:
Code Block class MainViewController: UINavigationController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white if isLoggedIn() { //#↓ If `TabBarViewController` does not suit for `init()` this may cause problems let tabBarController = TabBarViewController() viewControllers = [tabBarController] } else { //# I do not understand why you put 0.01 sec delay, //# but you should better not use `perform(_:with:afterDelay:)` DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { self.showLoginController() } } } fileprivate func isLoggedIn() -> Bool { return UserDefaults.standard.isLoggedIn() } private func showLoginController() { //#↓ When you instantiate a view controller desinged on the storyboard, //# you should use `instantiateViewController(identifier:)` guard let loginController = self.storyboard?.instantiateViewController(identifier: "loginVC") as? LoginViewController //#<- Replace `"loginVC"` to the right Storyboard ID else { print("Storyboard is not configured as expected") return } present(loginController, animated: true, completion: { //# If you do nothing here, you can pass `nil` to `completion:` }) } }
(Put a Storyboard ID to LoginViewController, and use it in instantiateViewController(identifier:).
I haven't checked other parts of your code. If this does not work, please tell me with detailed description.