I am trying to check for empty fields in the login page of IOS app using swift story board. The code is pasted below:
#IBOutlet weak var firstNameTextField: UITextField!
if (firstNameTextField.text?.isEmpty)! ||
(lastNameTextField.text?.isEmpty)! ||
(emailTextField.text?.isEmpty)! ||
(passwordTextField.text?.isEmpty)!{
userMessage(userMessage: "All fields are required")
return
}
I am getting the error:
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Can someone let me know what I am doing wrong here
Please make sure that all the outlets are connected properly.
Problem
The possible cause of the crash can be..
The result of firstNameTextField.text?.isEmpty may be null and you have used ! to unwrap so it get crashed
Or may possible that the IBOutlet is not connected to view controller in storyboard.
Solution
You can user if-let like below...
let fanme = firstNameTextField.text ?? ""
let lname = lastNameTextField.text ?? ""
let email = emailTextField.text ?? ""
let password = passwordTextField.text ?? ""
if fname.isEmpty || lname.isEmpty || email.isEmpty || password.isEmpty {
userMessage(userMessage: "All fields are required")
return
}
You must unwrap your variable and after check if tf are empty:
#IBOutlet weak var firstNameTextField: UITextField!
#IBOutlet weak var lastNameTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
Now write the func to check:
#objc func chekTfIsEmpty () {
guard let firstTF = firstNameTextField.text else { return } // unwrapped
guard let lastNameTF = lastNameTextField.text else { return } // unwrapped
guard let emailTF = emailTextField.text else { return } // unwrapped
guard let passTF = passwordTextField.text else { return } // unwrapped
if firstTF.isEmpty ||
lastNameTF.isEmpty ||
emailTF.isEmpty ||
passTF.isEmpty {
userMessage(userMessage: "All fields are required")
return
} else {
// do your stuff here
}
}
after that call the this function with your login button...
Related
Very basic code
I am doing coding at school and have to create an app. Part of the app is a water usage calculator. Even though I am checking for nil values from the optional, it gets the error: "Fatal Error: Unexpectedly found nil while unwrapping an optional". It finds this error during a random part of func btnCalculate.
import UIKit
class WaterCalcViewController: UIViewController {
//Inputs
#IBOutlet weak var txtShowers: UITextField!
#IBOutlet weak var txtBaths: UITextField!
#IBOutlet weak var txtDishwasher: UITextField!
#IBOutlet weak var txtWashingMachine: UITextField!
#IBOutlet weak var txtTeeth: UITextField!
#IBOutlet weak var txtToilet: UITextField!
#IBOutlet weak var txtNumOfPeople: UITextField!
//Inputs for the user to add values to their respective use of each item/thing
//Outputs
#IBOutlet weak var lblShowerError: UILabel!
#IBOutlet weak var lblBathError: UILabel!
#IBOutlet weak var lblDishwasherError: UILabel!
#IBOutlet weak var lblWashingMachineError: UILabel!
#IBOutlet weak var lblTeethError: UILabel!
#IBOutlet weak var lblToiletError: UILabel!
#IBOutlet weak var lblNumOfPeopleError: UILabel!
#IBOutlet weak var lblTotalSum: UILabel!
//Labels that appear when no value is given for their respective text field
//Functions
//Actions
#IBAction func btnBack(_ sender: Any) {
let destinationVC = self.storyboard?.instantiateViewController(identifier: "tabController") as! UITabBarController
destinationVC.selectedIndex = 3
destinationVC.modalPresentationStyle = .fullScreen
self.present(destinationVC, animated: true, completion: nil)
}
var success: Int = 0
#IBAction func btnCalculate(_ sender: Any) {
success = 0
let shower: Int? = Int(txtShowers.text!)
if shower != nil {
success = success + 1
} else if shower == nil {
lblShowerError.text = ("Please input a valid number")
}
let bath: Int? = Int(txtShowers.text!)
if bath != nil {
success = success + 1
} else if bath == nil {
lblBathError.text = ("Please input a valid number")
}
let dishwasher: Int? = Int(txtShowers.text!)
if dishwasher != nil {
success = success + 1
} else if dishwasher == nil {
lblDishwasherError.text = ("Please input a valid number")
}
let washingMachine: Int? = Int(txtShowers.text!)
if washingMachine != nil {
success = success + 1
} else if washingMachine == nil {
lblWashingMachineError.text = ("Please input a valid number")
}
let teethLength: Int? = Int(txtShowers.text!)
if teethLength != nil {
success = success + 1
} else if teethLength == nil {
lblTeethError.text = ("Please input a valid number")
}
let toiletFlushes: Int? = Int(txtShowers.text!)
if toiletFlushes != nil {
success = success + 1
} else if toiletFlushes == nil {
lblToiletError.text = ("Please input a valid number")
}
let numOfPeople: Int? = Int(txtShowers.text!)
if numOfPeople != nil {
success = success + 1
} else if numOfPeople == nil {
lblNumOfPeopleError.text = ("Please input a valid number")
}
if success == 7 {
var totalSum = (shower! * 10)
totalSum = totalSum + (bath! * 150)
totalSum = totalSum + (dishwasher! * 30)
totalSum = totalSum + (washingMachine! * 90)
totalSum = totalSum + (teethLength! * 5)
totalSum = totalSum + (numOfPeople! * 10)
totalSum = totalSum + (toiletFlushes! * Int(4.5))
lblTotalSum.text = ("Your average daily water use is \(totalSum)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard))
//Uncomment the line below if you want the tap not not interfere and cancel other interactions.
//tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
//Calls this function when the tap is recognized.
#objc func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
// Do any additional setup after loading the view.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
The issue can be you are trying to convert a nil value into Int.
Here in every this kind of line :- let shower: Int? = Int(txtShowers.text!) here txtShowers.text can be a nil or any other similar value try having a break point at this.
You can try this instead first get all the values which you want using guard let like this :-
guard let shower = txtShowers.text else {\\Show some error or what you want}
This will also reduce your number or lines of code.
and then you can perform the operations on shower easily.
Just for the info :- you should never use forcecast in your code always try to go with guard let or if let
Function moveToHome gives error when stating the viewcontroller class. Use of undeclared type 'HomeViewController'. I set the class of the view controller to HomeViewController but it is not being recognized.
import Foundation
import UIKit
import Firebase
import SwiftKeychainWrapper
import FirebaseAuth
import FirebaseFirestore
class SignUpEmail: UIViewController {
#IBOutlet weak var Email: UITextField!
#IBOutlet weak var Password: UITextField!
#IBOutlet weak var Firstname: UITextField!
#IBOutlet weak var Lastname: UITextField!
#IBOutlet weak var City: UITextField!
#IBOutlet weak var Street: UITextField!
#IBOutlet weak var Gender: UITextField!
#IBOutlet weak var SignupButton: UIButton!
#IBOutlet weak var errorLAbel: UILabel!
var userUid: String!
override func viewDidLoad() {
super.viewDidLoad()
SignupButton.layer.cornerRadius = 15
errorLAbel.alpha = 0
}
// Check fields, If everything is correct returns Nil otherwise returns error.
func validateFields() -> String? {
if Email.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Password.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Firstname.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Lastname.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
City.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Street.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
Gender.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
return "Please fill in all fields."
}
// Check if password is secure
let cleanedPassword = Password.text!.trimmingCharacters(in: .whitespacesAndNewlines)
if Utilities.isPasswordValid(cleanedPassword) == false {
// Password isn't secure enough
return "Please make sure your password is at least 8 characters, contains a special character and a number."
}
return nil
}
#IBAction func SignupTapped(_ sender: Any) {
//Validate
let error = validateFields()
if error != nil {
// Something is wrong with the fields
showError(error!)
}
else {
// Create User
// Create clean versions of data
let lastname = Lastname.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let firstname = Firstname.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let email = Email.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let password = Password.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let city = City.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let street = Street.text!.trimmingCharacters(in: .whitespacesAndNewlines)
let gender = Gender.text!.trimmingCharacters(in: .whitespacesAndNewlines)
Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
//check for errors
if err != nil {
// There was an error creating the user
self.showError("Error Creating User")
}
else {
//User was creating successfully now store
let db = Firestore.firestore()
db.collection("users").addDocument(data: ["firstname":firstname, "lastname":lastname, "City": city, "Street": street, "Gender":gender, "uid": result!.user.uid]) { (Error) in
if error != nil {
self.showError("Error saving user data")
}
}
// Move to homescreen
self.moveToHome()
}
}
}
}
func showError(_ message:String) {
errorLAbel.text = message
errorLAbel.alpha = 1
}
func moveToHome() {
let storyboard = UIStoryboard(name: "Main.storyboard", bundle: nil)
let homeViewController = storyboard?.instantiateViewController(identifier: "HomeVC") as? HomeViewController //This part gives error
view.window?.rootViewController = homeViewController
view.window?.makeKeyAndVisible()
}
}
(Ignore had to add extra text to be able to post)
try:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
uses "Main" instead of "Main.storyboard"
and make sure that the StoryboadID has been set
I have an "expected declaration" at this line:
if(userEmail.isEmpty || userPassword.isEmpty || userRepeatPassword.isEmpty)
Could you tell me why? Thank you in advance.
My code:
class RegisterPageViewController: UIViewController {
#IBOutlet weak var userEmailTextField: UITextField!
#IBOutlet weak var userPasswordTextField: UITextField!
#IBOutlet weak var repeatPasswordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func registerButtonTapped(_ sender: AnyObject) {
let userEmail = userEmailTextField.text;
let userPassword = userPasswordTextField.text;
let userRepeatPassword = repeatPasswordTextField.text
}
// Check for empty fields
if(userEmail.isEmpty || userPassword.isEmpty || userRepeatPassword.isEmpty)
{
// Display Alert Message
displayMyAlertMessage("All fields are required");
return;
}
Declare the variables in the class or even globally, not inside the button!
var userEmail: String = ""
var userPassword: String = ""
var userRepeatPassword: String = ""
Button declaration:
#IBAction func registerButtonTapped(_ sender: AnyObject) {
userEmail = userEmailTextField.text;
userPassword = userPasswordTextField.text;
userRepeatPassword = repeatPasswordTextField.text
}
if(userEmail.text == "" || userPassword.text == "" || userRepeatPassword.text == "")
{
// Display Alert Message
displayMyAlertMessage("All fields are required");
return;
}
or you can try
if(userEmail.text.isEmpty || userPassword.text.isEmpty || userRepeatPassword.text.isEmpty)
{
// Display Alert Message
displayMyAlertMessage("All fields are required");
return;
}
try to check blank string and it will work the same
I put the if statement inside a function and it worked.
Thank you for all your answers guys.
Like that:
func registerButtonTapped() {
let userEmail = ""
let userPassword = ""
let userRepeatPassword = ""
// Check for empty fields
if userEmail.isEmpty || userPassword.isEmpty || userRepeatPassword.isEmpty
{
// Display Alert Message
displayMyAlertMessage(userMessage:"All fields are required")
return
}
In my view controller:
class FoodAddViewController: UIViewController, UIPickerViewDataSource, UITextFieldDelegate, UIPickerViewDelegate {
let TAG = "FoodAddViewController"
// Retreive the managedObjectContext from AppDelegate
let managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
#IBOutlet weak var foodName: UITextField!
#IBOutlet weak var foodPortion: UITextField!
#IBOutlet weak var foodCalories: UITextField!
#IBOutlet weak var foodUnit: UILabel!
#IBOutlet weak var unitPicker: UIPickerView!
#IBOutlet weak var unitPickerViewContainer: UIVisualEffectView!
/*
unrelated code has been ommited
*/
func validateAllTextFields(textFields: [UITextField] = [foodName as UITextField, foodPortion, foodCalories]) -> Bool {
var result = true
for textField in textFields {
result = validateTextField(textField) && result
}
return result
}
func validateTextField(textField: UITextField) -> Bool{
let correctColor = UIColor.redColor().CGColor, normalColor = UIColor.blackColor().CGColor
var correct = true
if textField == foodPortion || textField == foodCalories{
if !Misc.isInteger(textField.text!){
correct = false
}
}
if textField.text!.isEmpty {
correct = false
}
textField.layer.borderColor = correct ? normalColor : correctColor
return correct
}
}
I have a few textfields, and in my validateTextField can verify one at a time, and I want my validateAllTextFields be able to verify a give list of textfield by checking them one by one, if the list is not given, I want to check a given default list that contains all three textfield.
The code I imagine to be something like:
func validateAllTextFields(textFields: [UITextField] = [foodName as UITextField, foodPortion, foodCalories]) -> Bool {
var result = true
for textField in textFields {
result = validateTextField(textField) && result
}
return result
}
However Xcode gives an error back:
instance member cannot be used on type viewcontroller
What's the cause and how to fix?
You cannot use instance variables in function declarations. Call the function with your textFields array and pass the parameters.
func validateAllTextFields(textFields: [UITextField] ) -> Bool {
var result = true
for textField in textFields {
result = validateTextField(textField) && result
}
return result
}
somehwere in your class:
validateAllTextFields(textFields: [foodName, foodPortion, foodCalories])
Or you check inside of your function if textFields is empty and than u use the instance variables
func validateAllTextFields(textFields: [UITextField] ) -> Bool {
if textFields.count == 0 {
textFields = [foodName, foodPortion, foodCalories]
}
var result = true
for textField in textFields {
result = validateTextField(textField) && result
}
return result
}
I'm making a simple search engine in xcode. It is supposed to work by seeing if the text in a textfield is equal to a value in a dictionary, and if so, do an action, like this:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var SearchField: UITextField!
#IBOutlet weak var SearchButton: UIButton!
#IBOutlet weak var Result1: UILabel!
#IBOutlet weak var Result2: UILabel!
var possibleResults = ["Daniel":"www.example.com", "Bob":"www.asdf.com"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
//if Go button is pressed
#IBAction func SearchButton(sender: AnyObject) {
//if Search field is equal to a value in possibleResults
if SearchField is equal to a value in possibleResults {
//makes result1 say hi
self.Result1.text = "Hi"
} else {
self.Result1.text = "No Results"
}
}
}
Also, keep in mind I am pretty new to Swift, so simple and direct answers would be helpful.
You can unwrap the text and check the result in one line, like following:
if let text = SearchField.text, result = possibleResults[text] {
print(result)
}
You can use:
if possibleResults[SearchField.text ?? ""] != nil {
// ...
}
or
if let _ = possibleResults[SearchField.text ?? ""] {
// ...
}
if you do not need value that you get from dictionary.
If you will use value from dictionary then replace underscore with variable name:
if let value = possibleResults[SearchField.text ?? ""] {
// ...
}