我正在尝试使用五个文本字段创建otp文本字段,如果您添加top都可以正常工作,但是当用户尝试将文本字段添加为空并尝试退格并且未调用UItextfiled的任何委托方法时发生了问题添加。
我尝试过这个:-
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let char = string.cStringUsingEncoding(NSUTF8StringEncoding)!
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) {
println("Backspace was pressed")
}
return true
}
但是当文本字段不为空时调用它。
例如:-
在下面的屏幕快照中,添加1并在两个不同的文本字段中添加第三个文本字段,但是当我尝试退格时,需要在第二个文本字段中添加文本(第三个是字段为空),这是我面临的问题。
谢谢
答案 0 :(得分:7)
后面是@Marmik Shah和@Prashant Tukadiya的答案,在此我添加我的答案,为了快速回答,我从here中提取了一些代码
第1步:
为所有文本字段创建IBOutletCollection,也不要忘记按顺序在所有文本字段中设置标签,例如[1,2,3,4,5,6]
class ViewController: UIViewController{
@IBOutlet var OTPTxtFields: [MyTextField]! // as well as set the tag for textfield in the sequence order
override func viewDidLoad() {
super.viewDidLoad()
//change button color and other options
OTPTxtFields.forEach { $0.textColor = .red; $0.backspaceTextFieldDelegate = self }
OTPTxtFields.first.becomeFirstResponder()
}
第2步:
在当前页面的UITextField委托方法中
extension ViewController : UITextFieldDelegate, MyTextFieldDelegate {
func textFieldDidEnterBackspace(_ textField: MyTextField) {
guard let index = OTPTxtFields.index(of: textField) else {
return
}
if index > 0 {
OTPTxtFields[index - 1].becomeFirstResponder()
} else {
view.endEditing(true)
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let newString = ((textField.text)! as NSString).replacingCharacters(in: range, with: string)
if newString.count < 2 && !newString.isEmpty {
textFieldShouldReturnSingle(textField, newString : newString)
// return false
}
return newString.count < 2 || string == ""
//return true
}
override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copy(_:)) || action == #selector(paste(_:)) {
return false
}
return true
}
func textFieldShouldReturnSingle(_ textField: UITextField, newString : String)
{
let nextTag: Int = textField.tag + 1
textField.text = newString
let nextResponder: UIResponder? = textField.superview?.viewWithTag(nextTag)
if let nextR = nextResponder
{
// Found next responder, so set it.
nextR.becomeFirstResponder()
}
else
{
// Not found, so remove keyboard.
textField.resignFirstResponder()
callOTPValidate()
}
}
}
第3步:
创建文本字段类以访问向后功能
class MyTextField: UITextField {
weak var myTextFieldDelegate: MyTextFieldDelegate?
override func deleteBackward() {
if text?.isEmpty ?? false {
myTextFieldDelegate?.textFieldDidEnterBackspace(self)
}
super.deleteBackward()
}
}
protocol MyTextFieldDelegate: class {
func textFieldDidEnterBackspace(_ textField: MyTextField)
}
步骤-4
最后按照@Marmik Shah的答案为UITextField定制类
第5步
从每个文本字段获取值
func callOTPValidate(){
var texts: [String] = []
OTPTxtFields.forEach { texts.append($0.text!)}
sentOTPOption(currentText: texts.reduce("", +))
}
func sentOTPOption(currentText: String) {
print("AllTextfieldValue == \(currentText)")
}
答案 1 :(得分:1)
您可以覆盖函数deleteBackward()
创建一个继承UITextField并触发和EditingEnd事件的新类。
class MyTextField: UITextField {
override func deleteBackward() {
super.deleteBackward()
print("Backspace");
self.endEditing(true);
}
}
然后,在情节提要中为UITextField添加自定义类
接下来,在视图控制器中的editingEnd操作中,可以切换文本字段。为此,您需要为每个文本字段设置一个标记值。
例如,您有两个文本字段tfOne和tfTwo。
tfOne.tag = 1; tfTwo.tag = 2
现在,如果当前正在编辑tfTwo并单击退格键,则将当前正在编辑的文本字段设置为tfOne
class ViewController: UIViewController {
@IBOutlet weak var tfOne: MyTextField!
@IBOutlet weak var tfTwo: MyTextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func editingEnded(_ sender: UITextField) {
// UITextField editing ended
if(sender.tag == 2) {
self.tfOne.becomeFirstResponder();
}
}
}
答案 2 :(得分:1)
您可以按顺序将标签赋予文本字段,例如101,102,103,104,105。
点击退格键时。检查字符串的长度等于0。然后goto textfield.tag-1,直到获得第一个textfield。就像您在textfield 102上一样,那么goto textfield 102-1 =101。
与输入任何字符时一样,直到下一个文本字段,直到您到达最后一个文本字段,就像您在文本字段102上一样,然后转到文本字段102 + 1 =103。
您可以使用(self.view.viewWithTag(yourTag) as? UITextField)?.becomeFirstResponder()
我没有系统,所以无法发布代码