Edit:
This question is a case study in how not to ask a question on SO. The OP provides incomplete information, and several people engage in an extended game of 20 questions trying to figure out what's going on.
To the OP: You need to edit your question and include all the information we managed to get from you in the following comments in the original question. That's important for future readers of this thread. The question is a lot harder to follow if readers have to wade through dozens of comments to figure out the details of the question.
The cause of your crash:
You state in one of your comments that you present your view controller with the line present(LoginScreenViewController(), animated: true)
.
That creates an instance of LoginScreenViewController
by calling its default initializer, LoginScreenViewController()
.
You can't do that for view controllers who's views are loaded from a storyboard. Calling the default initializer will not load the views from the Storyboard. All your outlets will be nil. The view controller's content view will be nil.
The fix:
You need to load view controllers from a storyboard by calling one of the UIStoryboard
instantiate methods (like instantiateViewController(withIdentifier:)
.)
Also, IBOutlets are set up as "implicitly unwrapped optionals" by default. That means that when you try to reference the outlet, the compiler will silently (implicitly) try to unwrap them, and if they are nil, your code will crash.
If code that references an outlet crashes, it is likely nil. You need to go figure out why it's nil.
In your textFieldShouldReturn(_:)
method, you reference both phoneAndEmailTextField
and passwordTextField
. They are both declared as implicitly unwrapped optionals, meaning if either of those outlets is not connected in your storyboard, that function will crash.
Try rewriting that function like this:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
guard let phoneAndEmailTextField = phoneAndEmailTextField else {
print("phoneAndEmailTextField is nil")
return false
}
guard let passwordTextField = passwordTextField else {
print("passwordTextField is nil")
return false
}
phoneAndEmailTextField?.endEditing(true)
passwordTextField?.endEditing(true)
return true
}
(Note that with implicitly unwrapped optionals, if you reference them with a question mark as I did in the edited version of your function, the compiler will still do optional chaining and skip the function call/property reference if the thing being referenced is nil.)
Edit:
If it's the statement phoneAndEmailTextField.delegate = self
that's crashing, that tells you that phoneAndEmailTextField
is nil. You must be doing something wrong in hooking up your IBOutlets. Add a screenshot of your view controller to your question with the connections inspector shown so we can see the connections of those two outlets.
You could fix the crash by rewriting the line as phoneAndEmailTextField?.delegate = self
but the phoneAndEmailTextField outlet will still be nil, so you will only be patching the problem, not fixing it.
BTW, you can connect your text field delegates to your view controller right in your storyboard. Just select the text field, pick the connections inspector, and drag from the delegate connection onto the view controller in the storyboard.