【问题标题】:Prevent UITextField from taking values on changing the firstResponder防止 UITextField 在更改 firstResponder 时取值
【发布时间】:2017-12-12 11:00:06
【问题描述】:

我有四个 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 后将文本设置为空,但它不起作用。我该如何解决这个问题?谢谢。

【问题讨论】:

    标签: ios swift uitextfield resignfirstresponder becomefirstresponder


    【解决方案1】:

    由于textField(_:shouldChangeCharactersIn:replacementString:) 执行之前文本出现在文本字段中,您应该将代码放在文本已更改时调用的方法中。

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

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

    单独处理每个文本字段也是非常多余的。我建议将您的文本字段包含在一个数组中并遍历它们。

    【讨论】:

      【解决方案2】:

      shouldChangeCharactersInRange 在填充 textField 之前被调用。你可以这样做:

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

      为 viewDidLoad() 中的所有文本字段写上一行

          @objc func textFieldChangedValue(textField: UITextField) {
          print(textField.text)
      }
      

      这会起作用

      【讨论】:

        【解决方案3】:

        根据@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
            }
        }
        

        而且,在我必须实现恢复代码提交的视图控制器中,我只是简单地继承了 FillUpCodeViewController 类。

        RecoveryViewController.swift

        override func viewDidLoad() {
        
            setupArrrayofTextFields(textField1: textFieldRecoveyCodeFirstDigit,
                                    textField2: textFieldRecoveyCodeSecondDigit,
                                    textField3: textFieldRecoveyCodeThirdDigit,
                                    textField4: textFieldRecoveyCodeFourthDigit)
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-25
          • 1970-01-01
          • 2021-10-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多