在 Swift 的文本字段中自动辞职并分配第一响应者

Auto Resign and assign first responder in text field in Swift

我已经使用了 3 个文本字段并希望它们只包含一个整数用于 OTP 目的(这是项目设计的需要)。当用户在第一个文本字段中输入数字时,响应程序应自动分配给第二个文本字段,然后分配给第三个文本字段。一旦用户在第三个文本字段中输入最后一个 OTP 数字,我就想点击网络服务。到目前为止我所做的是:

class ActivationCodeVC: UIViewController, UITextFieldDelegate

然后

otpField1.delegate = self
otpField2.delegate = self
otpField3.delegate = self

然后

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    let text=textField.text
    let counter = text?.characters.count
    if counter >= 1 {

        if textField == otpField1{

            otpField2.becomeFirstResponder()

        } else if textField == otpField2{

            otpField3.becomeFirstResponder()

        } else if textField == otpField3{

            otpField3.resignFirstResponder()

        }

    }

    return true
}

当用户在第一个文本字段中输入数字时,光标应该在第二个文本字段上开始闪烁。但事实并非如此。在我按下第二个数字后,它会将其输入到第二个文本字段,然后光标不会再次移动到第三个,而是保留在第二个文本字段中。其次,当我尝试通过退格键删除数字时,例如,当我尝试删除第一个文本字段数字时,它会从第二个文本字段中删除数字。

请帮助我应该实现哪些方法以及如何正确实现功能。

我试过了,但字符打印在第二个文本字段中,而不是第一个,依此类推。

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    let text = textField.text
    // create Range<Index> object from old-style one
    let start = text!.startIndex.advancedBy(range.location)
    let end = start.advancedBy(range.length)
    let indexRange = start..<end
    // calculate result string value
    let result = text!.stringByReplacingCharactersInRange(indexRange, withString: string)

//        let text=textField.text
    let tempCount = result.characters.count
    if tempCount == 1 {

        if textField == otpField1{

            otpField2.becomeFirstResponder()

        } else if textField == otpField2{

            otpField3.becomeFirstResponder()

        } else if textField == otpField3{

            otpField3.resignFirstResponder()

            let tempCode = otpField1.text! + otpField2.text! + otpField3.text!

            if  !APPDELEGATE.internetStatusFalse {
                KVNProgress.showWithStatus("Loading...")
                let soapApiObj: SoapApi = SoapApi()
                mode = ControllerTypeMode.ACTIVAITONCODE
                soapApiObj.resDelegate = self
                soapApiObj.responseString = NSMutableString(string: "")
                soapApiObj.callActivationCodeApi(tempCode)
            }
            else{
                let obj: SuccessFullPopVC=self.storyboard?.instantiateViewControllerWithIdentifier("successFullPopVC") as! SuccessFullPopVC
                obj.titlelbl = LocalizationSystem.sharedLocalSystem().localizedStringForKey("Warning", value: nil)
                obj.imgSuccess = UIImage(named: "warning")
                obj.messagelbl = LocalizationSystem.sharedLocalSystem().localizedStringForKey("No internet connection.", value: nil)
                self.navigationController?.presentViewController(obj, animated: false, completion: nil)
            }

        }

    }

    return true
}

感谢最终解决方案:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    let text = textField.text
    // create Range<Index> object from old-style one
    let start = text!.startIndex.advancedBy(range.location)
    let end = start.advancedBy(range.length)
    let indexRange = start..<end
    // calculate result string value
    let result = text!.stringByReplacingCharactersInRange(indexRange, withString: string)

    let newLength = result.characters.count

    if textField == otpField1{
        if newLength == 1 {
            otpField1.text = result
            otpField2.becomeFirstResponder()
            return false
        }

    } else if textField == otpField2{
        if newLength == 1 {
            otpField2.text = result
            otpField3.becomeFirstResponder()
            return false
        }

    } else if textField == otpField3{
        if newLength == 1 {
            otpField3.text = result
            return false

        }

    }

    return !(result.characters.count>1)
}

有效!!

shouldChangeCharactersInRange-委托方法在实际文本更改(在您的情况下为字符 put/delete)之前被调用。

首先计算输入动作后得到的字符串。使用委托方法参数(rangestring)和 textField.text,如下面的代码片段所示。

let text = textField.text
// create Range<Index> object from old-style one
let start = text.startIndex.advancedBy(range.location)
let end = start.advancedBy(range.length)
let indexRange = start..<end
// calculate result string value
let result = text.stringByReplacingCharactersInRange(indexRange, withString: string)

Updated for Swift 3:

使用下面的简单代码:

//To asssing next responder
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if (textField == self.nameTextField) {
        self.textField = self.emailTextField
        self.emailTextField.becomeFirstResponder()
    } else if (textField == self.emailTextField) {
        self.textField = self.phoneNumberTextfield
        self.phoneNumberTextfield.becomeFirstResponder()
    } else if(textField == self.phoneNumberTextfield) {
        self.textField = self.amountTextField
        self.amountTextField.becomeFirstResponder()
    } else if (textField == self.amountTextField) {
        self.textField = self.descriptionTextField
        self.descriptionTextField.becomeFirstResponder()
    } else {
        textField.resignFirstResponder()
    }
    return false
}