在 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)之前被调用。
首先计算输入动作后得到的字符串。使用委托方法参数(range
、string
)和 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
}
我已经使用了 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)之前被调用。
首先计算输入动作后得到的字符串。使用委托方法参数(range
、string
)和 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
}