Reputation: 11
Created 6 UITextFields
for user OTP inputs. I have tried many ways but it keeps returning - Cannot assign value of type 'UITextField
?' to type 'String
?'
import UIKit
import Firebase
class OTPRequestViewController: UIViewController, UITextFieldDelegate{
var verifyfromRegistration = RegisterViewController()
@IBOutlet weak var textOTP1: UITextField!
@IBOutlet weak var textOTP2: UITextField!
@IBOutlet weak var textOTP3: UITextField!
@IBOutlet weak var textOTP4: UITextField!
@IBOutlet weak var textOTP5: UITextField!
@IBOutlet weak var textOTP6: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
textOTP1.delegate = self
textOTP2.delegate = self
textOTP3.delegate = self
textOTP4.delegate = self
textOTP5.delegate = self
textOTP6.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if (textField.text!.count < 1) && (string.count > 0) {
if textField == textOTP1 {
textOTP2.becomeFirstResponder()
}
if textField == textOTP2 {
textOTP3.becomeFirstResponder()
}
if textField == textOTP3 {
textOTP4.becomeFirstResponder()
}
if textField == textOTP4 {
textOTP5.becomeFirstResponder()
}
if textField == textOTP5 {
textOTP6.becomeFirstResponder()
}
if textField == textOTP6 {
textOTP6.resignFirstResponder()
}
textField.text = string
return false
}else if (textField.text!.count >= 1) && (string.count == 0) {
if textField == textOTP2 {
textOTP1.becomeFirstResponder()
}
if textField == textOTP3 {
textOTP2.becomeFirstResponder()
}
if textField == textOTP4 {
textOTP3.becomeFirstResponder()
}
if textField == textOTP5 {
textOTP4.becomeFirstResponder()
}
if textField == textOTP6 {
textOTP5.becomeFirstResponder()
}
if textField == textOTP1 {
textOTP1.resignFirstResponder()
}
textField.text = ""
return false
} else if (textField.text!.count) >= 1 {
textField.text = string
return false
}
return true
}
@IBAction func oTPButtonPressed(_ sender: UIButton) {
guard let otpCode = textOTP1.text else {return}
guard let verificationiD = verifyfromRegistration.defaults.string(forKey: "verificationId") else {return}
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationiD, verificationCode: otpCode)
Auth.auth().signInAndRetrieveData(with: credential) { (success, error) in
if error == nil {
print("User Signed in! Sucess!!")
self.performSegue(withIdentifier: "goToOTPVerified", sender: self)
}else {
print("Something went wrong!")
}
}
}
The expected output is to merge the out puts of the 6 UItextField
and send it to a let property
Upvotes: 0
Views: 709
Reputation: 130152
First of all, you should put your fields into an array:
var otpFields: [UITextField] {
return [textOTP1!, textOTP2!, textOTP3!, textOTP4!, textOTP5!, textOTP6!]
}
Then getting the full input is easy:
let otpCode = otpFields.compactMap { $0.text }.joined()
Also note that putting fields into an array can significantly simplify your code, e.g. :
if (textField.text!.count < 1) && (string.count > 0) {
guard let index = otpFields.index(where: { $0 === textField }) else { return }
if index + 1 < fields.count {
otpFields[index + 1].becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
}
Upvotes: 1