I'v ten textfields like otp for mobile number.I've handled all cases except like if user write digit in first textfield and focus goes to second textfield.Second textfield is empty and when i press the delete button focus not goes to pervious field.So, how i can handle empty textfield case when textfield is empty and user press the delete button.
@IBOutlet weak var textFieldNumber1: UITextField!
@IBOutlet weak var textFieldNumber2: UITextField!
@IBOutlet weak var textFieldNumber3: UITextField!
@IBOutlet weak var textFieldNumber4: UITextField!
@IBOutlet weak var textFieldNumber5: UITextField!
@IBOutlet weak var textFieldNumber6: UITextField!
@IBOutlet weak var textFieldNumber7: UITextField!
@IBOutlet weak var textFieldNumber8: UITextField!
@IBOutlet weak var textFieldNumber9: UITextField!
@IBOutlet weak var textFieldNumber10: UITextField!
@IBOutlet weak var textFieldPassword: UITextField!
func setupTextFields() {
[textFieldNumber1,textFieldNumber2,textFieldNumber3,textFieldNumber4,textFieldNumber5,textFieldNumber6,textFieldNumber7,textFieldNumber8,textFieldNumber9,textFieldNumber10].forEach {
$0?.keyboardType = .numberPad
$0?.delegate = self
$0?.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
}
}
@objc func textFieldDidChange(_ textField: UITextField) {
guard let text = textField.text else {return}
let char = text.cString(using: String.Encoding.utf8)
let isBackSpace = strcmp(char, "\\b")
if isBackSpace == -92 {
switch textField.tag {
case 1:
counterTextFieldPhoneNumber -= 1
case 2:
textFieldNumber1.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 3:
textFieldNumber2.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 4:
textFieldNumber3.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 5:
textFieldNumber4.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 6:
textFieldNumber5.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 7:
textFieldNumber6.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 8:
textFieldNumber7.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 9:
textFieldNumber8.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
case 10:
textFieldNumber9.becomeFirstResponder()
counterTextFieldPhoneNumber -= 1
default:
break
}
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let char = string.cString(using: String.Encoding.utf8)
let isBackSpace = strcmp(char, "\\b")
if !(isBackSpace == -92) {
if (counterTextFieldPhoneNumber >= 0 || counterTextFieldPhoneNumber <= 10) {
switch textField.tag {
case 1:
textFieldNumber1.text = string
textFieldNumber2.becomeFirstResponder()
textFieldNumber2.text = ""
counterTextFieldPhoneNumber += 1
case 2:
textFieldNumber2.text = string
textFieldNumber3.becomeFirstResponder()
textFieldNumber3.text = ""
counterTextFieldPhoneNumber += 1
case 3:
textFieldNumber3.text = string
textFieldNumber4.becomeFirstResponder()
textFieldNumber4.text = ""
counterTextFieldPhoneNumber += 1
case 4:
textFieldNumber4.text = string
textFieldNumber5.becomeFirstResponder()
textFieldNumber5.text = ""
counterTextFieldPhoneNumber += 1
case 5:
textFieldNumber5.text = string
textFieldNumber6.becomeFirstResponder()
textFieldNumber6.text = ""
counterTextFieldPhoneNumber += 1
case 6:
textFieldNumber6.text = string
textFieldNumber7.becomeFirstResponder()
textFieldNumber7.text = ""
counterTextFieldPhoneNumber += 1
case 7:
textFieldNumber7.text = string
textFieldNumber8.becomeFirstResponder()
textFieldNumber8.text = ""
counterTextFieldPhoneNumber += 1
case 8:
textFieldNumber8.text = string
textFieldNumber9.becomeFirstResponder()
textFieldNumber9.text = ""
counterTextFieldPhoneNumber += 1
case 9:
textFieldNumber9.text = string
textFieldNumber10.becomeFirstResponder()
textFieldNumber10.text = ""
counterTextFieldPhoneNumber += 1
case 10:
textFieldNumber10.text = string
textFieldNumber10.resignFirstResponder()
counterTextFieldPhoneNumber += 1
guard let tf1 = textFieldNumber1.text,
let tf2 = textFieldNumber2.text,
let tf3 = textFieldNumber3.text,
let tf4 = textFieldNumber4.text,
let tf5 = textFieldNumber5.text,
let tf6 = textFieldNumber6.text,
let tf7 = textFieldNumber7.text,
let tf8 = textFieldNumber8.text,
let tf9 = textFieldNumber9.text,
let tf10 = textFieldNumber10.text
else {return false}
if tf1.isEmpty || tf2.isEmpty || tf3.isEmpty || tf4.isEmpty || tf5.isEmpty || tf6.isEmpty || tf7.isEmpty || tf8.isEmpty || tf9.isEmpty || tf10.isEmpty {return false}
viewModel.phoneNumber = "\(tf1)\(tf2)\(tf3)\(tf4)\(tf5)\(tf6)\(tf7)\(tf8)\(tf9)\(tf10)"
default:
break
}
}
}
return true
}
You can call this function 'deleteBackward' for every UITextField
public override func deleteBackward() {
super.deleteBackward()
// Logic for cursor move one field to another
}
Example: https://github.com/amitcse6/ASOtpTextField
CustomTextField:
public override func deleteBackward() {
super.deleteBackward()
customDelegate?.textFieldDidDelete(self)
}
ViewController:
extension ASOtpTextFieldView: ASOtpTextFieldDelegate {
public func textFieldDidDelete(_ textField: ASOtpField) {
let updatedText = textField.text ?? ""
if updatedText.count == 0 {
goPreviousField(selectedTextField: textField)
}
}
}
func goPreviousField(selectedTextField: ASOtpField) {
if let textFields = textFields {
textFields.forEach({ (textField) in
if selectedTextField.index == textField.index, selectedTextField.index > 0 {
DispatchQueue.main.async {
selectedTextField.resignFirstResponder()
textFields[selectedTextField.index-1].textField?.becomeFirstResponder()
}
return
}
})
}
}