阻止UITextField在更改firstResponder时获取值

时间:2017-12-12 11:00:07

标签: ios swift uitextfield resignfirstresponder becomefirstresponder

我有四个UITextField,每个UITextField代表OTP的一个数字。我希望控件在用户输入代码时切换到连续的文本字段。我的实现如下。

extension FillSignUpCodeController: UITextFieldDelegate {

    func textFieldDidBeginEditing(_ textField: UITextField) {
        textField.text = ""
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let inputString = (textField.text! as NSString).replacingCharacters(in: range, with: string)

        if inputString.count == 1 {
            switch textField {

            case textFieldCodeFirstDigit:
                textFieldCodeFirstDigit.text = inputString
                textFieldCodeFirstDigit.resignFirstResponder()
                textFieldCodeSecondDigit.becomeFirstResponder()

            case textFieldCodeSecondDigit:
                textFieldCodeSecondDigit.text = inputString
                textFieldCodeSecondDigit.resignFirstResponder()
                textFieldCodeThirdDigit.becomeFirstResponder()

            case textFieldCodeThirdDigit:
                textFieldCodeThirdDigit.text = inputString
                textFieldCodeThirdDigit.resignFirstResponder()
                textFieldCodeFourthDigit.becomeFirstResponder()

            case textFieldCodeFourthDigit:
                textFieldCodeFourthDigit.text = inputString
                textFieldCodeFourthDigit.resignFirstResponder()

            default:
                return false
            }
        }
        return true
    }
}

使用这段代码,当用户键入第一个数字时,第一个文本字段获取输入值并将控件移动到下一个文本字段。但是,第二个文本字段取第一个数字的值。我在更改firstResponder后尝试将文本设置为空,但它不起作用。我该如何解决这个问题?感谢。

3 个答案:

答案 0 :(得分:1)

由于textField(_:shouldChangeCharactersIn:replacementString:)在之前执行,文本字段中存在文本,您应该将代码放在文本已经更改

您应该观察文本字段的更改并在那里执行响应者更改代码。您可以找到有关in this question的更多信息。

此外,在更改第一响应者之前辞职是多余的,您不需要这样做。

分别处理每个文本字段也非常冗余。我建议将你的文本字段包含在一个数组中并迭代它们。

答案 1 :(得分:1)

在填充textField之前调用shouldChangeCharactersInRange。您可以通过以下方式完成:

    textField.addTarget(self, action: #selector(textFieldChangedValue(textField:)), for: UIControlEvents.editingChanged)

在viewDidLoad()

中为所有文本字段写上面一行
    @objc func textFieldChangedValue(textField: UITextField) {
    print(textField.text)
}

这将有效

答案 2 :(得分:1)

根据@ the4kman和@Rahul Dasgupta的答案,我实施了以下内容:

FillUpCodeViewController.swift

override func viewDidLoad() {

    setupArrrayofTextFields(textField1: textFieldCodeFirstDigit,
                            textField2: textFieldCodeSecondDigit,
                            textField3: textFieldCodeThirdDigit,
                            textField4: textFieldCodeFourthDigit)
}

func setupArrrayofTextFields(textField1: UITextField, textField2: UITextField,
                             textField3: UITextField, textField4: UITextField) {

    arrayOftextFields = [textField1, textField2, textField3, textField4]
    for textField in arrayOftextFields {
        textField.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: .editingChanged)
    }
}

@objc func textFieldDidChange(textField: UITextField) {
    guard textField.text?.count == 0 else {
        let index: Int = arrayOftextFields.index(of: textField)!
        guard index == (arrayOftextFields.count-1) else {
            arrayOftextFields[index+1].becomeFirstResponder()
            return
        }
        textField.resignFirstResponder()
        return
    }
}

而且,在我必须实现恢复代码提交的viewcontroller中,我只是继承了FillUpCodeViewController类。

RecoveryViewController.swift

override func viewDidLoad() {

    setupArrrayofTextFields(textField1: textFieldRecoveyCodeFirstDigit,
                            textField2: textFieldRecoveyCodeSecondDigit,
                            textField3: textFieldRecoveyCodeThirdDigit,
                            textField4: textFieldRecoveyCodeFourthDigit)
}