1

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
    }
Shaikh
  • 47
  • 4

1 Answers1

1

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
            }
        })
    }
}
AMIT
  • 906
  • 1
  • 8
  • 20