textfield backspace action identify when textfield is empty?

梦想的初衷 提交于 2019-12-13 12:17:34

问题


I am trying to create otp textfield using five textfield.All working fine if you add top, but issue is occurred when user try to add textfield empty and trying to backspace and it was not call any delegate method of UItextfiled which I already added.

I tried this :-

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
}

but it's called when textfield is not empty.

For example :-

In below screen shot add 1 and on two different textfield and third one is empty but when I try to backspace it's need to go in second textfield(third is field is empty) this is what I was facing issue from mine side.

Thanks


回答1:


followed by @Marmik Shah and @Prashant Tukadiya answer here I add my answer , for quick answer I taken the some code from here

step 1 :

create the IBOutletCollection for your all textfields as well as don't forget to set the tag in all textfields in the sequence order, for e.g [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()
}

step 2 :

in your current page UITextField delegate method

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()
    }
}

}

Step 3:

create the textfield class for access the backward function

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)
}

step - 4

finally follow the @Marmik Shah answer for custom class for your UITextField

Step 5

get the values from each textfield use this

func callOTPValidate(){
    var texts:  [String] = []
    OTPTxtFields.forEach {  texts.append($0.text!)}
    sentOTPOption(currentText: texts.reduce("", +))

}

  func  sentOTPOption(currentText: String)   {
    print("AllTextfieldValue == \(currentText)")
  }



回答2:


You can give tag to your textfield in sequence like 101,102,103,104,105.

when backspace tapped. check the length of string is equal to 0. then goto textfield.tag - 1 until you get first textfield.like if you are on textfield 102 then goto textfield 102-1 = 101.

Same as when enter any character goto next textfield until you reach to last textfield like if you are on textfield 102 then goto textfield 102+1 = 103.

You can use (self.view.viewWithTag(yourTag) as? UITextField)?.becomeFirstResponder()

I don't have system with me so couldn't able to post code




回答3:


You can override the function deleteBackward()
Create a new Class that inherits UITextField and trigger and EditingEnd event.

class MyTextField: UITextField {
    override func deleteBackward() {
        super.deleteBackward()
        print("Backspace");
        self.endEditing(true);
    }
}

Then, in your Storyboard, add a custom class for the UITextField

Next, in your view controller, in the editingEnd action, you can switch the textfield. For this to work, you will need to set a tag value for each of your textfield.
For example, you have two text fields, tfOne and tfTwo.
tfOne.tag = 1; tfTwo.tag = 2
Now, if currently you are editing tfTwo and backspace is clicked, then you set the currently editing text field to 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();
        }
    }
}


来源:https://stackoverflow.com/questions/53665104/textfield-backspace-action-identify-when-textfield-is-empty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!