ios - 带有六个单字符文本字段的 OTP 输入表单
问题描述
我正在开发一个应用程序,在该应用程序中,我必须通过 6 个文本字段传递 6 位 OTP,在其中您只提供一个字符,然后它会自动转到另一个文本字段。我创建了 6 个 textFields 插座并使用了这段代码。我遇到的问题是我想更改特定的textField
OTP 编号,但问题是如果我想在点击十字按钮后更改文本字段 4 的 OTP 编号,它会自动转到文本字段 3。我该如何解决这个问题?
我使用的代码:
import UIKit
class OneTimePasswordViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var txtOTP1: UITextField!
@IBOutlet weak var txtOTP2: UITextField!
@IBOutlet weak var txtOTP3: UITextField!
@IBOutlet weak var txtOTP4: UITextField!
@IBOutlet weak var txtOTP5: UITextField!
@IBOutlet weak var txtOTP6: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
txtOTP1.delegate = self
txtOTP2.delegate = self
txtOTP3.delegate = self
txtOTP4.delegate = self
txtOTP5.delegate = self
txtOTP6.delegate = self
self.txtOTP1.becomeFirstResponder()
}
}
这是创建逻辑的代码:
func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool {
if (range.length == 0){
if textField == txtOTP1 {txtOTP2?.becomeFirstResponder()}
if textField == txtOTP2 {txtOTP3?.becomeFirstResponder()}
if textField == txtOTP3 {txtOTP4?.becomeFirstResponder()}
if textField == txtOTP4 {txtOTP5?.becomeFirstResponder()}
if textField == txtOTP5 {txtOTP6?.becomeFirstResponder()}
if textField == txtOTP6 {txtOTP6?.resignFirstResponder()}
textField.text? = string
return false
}
else if (range.length == 1) {
if textField == txtOTP6 {txtOTP5?.becomeFirstResponder()}
if textField == txtOTP5 {txtOTP4?.becomeFirstResponder()}
if textField == txtOTP4 {txtOTP3?.becomeFirstResponder()}
if textField == txtOTP3 {txtOTP2?.becomeFirstResponder()}
if textField == txtOTP2 {txtOTP1?.becomeFirstResponder()}
if textField == txtOTP1 {txtOTP1?.resignFirstResponder()}
textField.text? = ""
return false
}
return true
}
解决方案
您可以尝试我的 3rd 方库:- https://github.com/Datt1994/DPOTPView
对于解决方案: -
在 viewDidLoad 添加标签和委托给所有textfield
import UIKit
class OneTimePasswordViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var txtOTP1: UITextField!
@IBOutlet weak var txtOTP2: UITextField!
@IBOutlet weak var txtOTP3: UITextField!
@IBOutlet weak var txtOTP4: UITextField!
@IBOutlet weak var txtOTP5: UITextField!
@IBOutlet weak var txtOTP6: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
txtOTP1.delegate = self
txtOTP1.tag = 1000
txtOTP2.delegate = self
txtOTP2.tag = 2000
txtOTP3.delegate = self
txtOTP3.tag = 3000
txtOTP4.delegate = self
txtOTP4.tag = 4000
txtOTP5.delegate = self
txtOTP5.tag = 5000
txtOTP6.delegate = self
txtOTP6.tag = 6000
self.txtOTP1.becomeFirstResponder()
}
}
在 UITextFieldDelegate 扩展实现shouldChangeCharactersIn
功能如下所示,它也将与textField.textContentType = .oneTimeCode
extension OneTimePasswordViewController : UITextFieldDelegate {
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.trimmingCharacters(in: CharacterSet.whitespaces).count != 0 {
textField.text = string
if textField.tag < count*1000 {
let next = textField.superview?.viewWithTag((textField.tag/1000 + 1)*1000)
next?.becomeFirstResponder()
} else if textField.tag == count*1000 {
textField.resignFirstResponder()
}
} else if string.count == 0 { // is backspace
textField.text = ""
}
return false
}
}
推荐阅读
- masstransit - Masstransit 主机连接失败
- swift - 使用 JSONDecoder 的数组与字典响应结构
- c# - ' RSA.FromXmlString '此平台不支持操作。
- android - 使用字符串变量作为对象键
- java - android pie 或 api 级别 28 上的套接字无法正常工作。我无法使用主机与 Socket 连接并在 android java 中发布
- flutter - 如何在 Flutter 中渲染 3D 对象?
- python - 运行和调试时输出不同
- python - 如何将过滤后的 pyshark FileCapture 保存到新的 pcap 文件中?
- arrays - Swift - 不同大小的块数组
- v8 - V8 隔离映射内存泄漏