Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift UITextField deleteBackward Issue

I have a series of textfields in a single row. Each textfield is limited to two characters.

My problem is that I want to delete all the characters and go back through all the textfields until I get to the first textfield.

I have subclassed the textfield and overridden the deleteBackward method to determine if the text in the textfield is empty. If so then change the responder to the previous textfield.

This is all fine, but when there is one character in the textfield and backspace is pressed, the character is deleted and the responder is changed to the previous textfield.

This is incorrect behaviour as I want the focus to stay on that textfield that has had its character deleted and if the delete key is pressed again, then responder should change to previous textfield.

I corrected this my setting a flag in the shouldChangeCharacters delegate method of the textfield. The flag is set to true if ...

if (newLength == 0 && currentLength == 0) || currentLength == 0 {
  textFieldEmpty = true
} else {
  textFieldEmpty = false
}

This works fine, but when the textfield is empty, and backspace is pressed, this delegate method is not called?

Just wandering if anyone has solved a similar problem and what approach they may have taken?

Thanks

like image 594
Jack Of Diamonds Avatar asked Aug 08 '26 11:08

Jack Of Diamonds


1 Answers

I have a similar scenario but with single characters in every text field. I have also used deleteBackward in a custom textField to achieve this.

Try this code:

import UIKit
protocol CustomTextFieldDelegate{
 func textFieldDidDelete()
}
class CustomTextField: UITextField {
  var myCustomTextFieldDelegate : CustomTextFieldDelegate!
  override func deleteBackward() {
     super.deleteBackward()
     myCustomTextFieldDelegate.textFieldDidDelete()
 }
}

And this is how you should implement the deleteBackward method:

func textFieldDidDelete() {
    print("Entered Delete");
    print("Tag!!\(currentActiveTextField.tag)")
    var previousTag = 0
    if currentActiveTextField.text == ""{
      previousTag = currentActiveTextField.tag - 1
    }else{
     previousTag = currentActiveTextField.tag
    }
    let previousResponder = currentActiveTextField.superview?.viewWithTag(previousTag)
    if(previousTag > 0){
        let previousTextField = previousResponder as! CustomTextField
        previousTextField.text = ""
        currentActiveTextField = previousTextField
        previousResponder?.becomeFirstResponder()
    }
}

Also in shouldChangeCharacters in range method, dont forget to set your currentlyActiveTextField as the text field you wish to edit. Check the following code, might help. My text fields have tags 1,2,3,4.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    currentActiveTextField = textField as! CustomTextField
    let nextTag = textField.tag + 1;
    // get next responder
    var nextResponder = textField.superview?.viewWithTag(nextTag);


    // On inputing value to textfield
    if (textField.text?.characters.count < 1  && string.characters.count > 0){

        if (nextResponder == nil){
            nextResponder = textField.superview?.viewWithTag(1);
        }
        textField.text = string;

        if nextTag == 5 {
            self.digitFourTextField.resignFirstResponder()
            return true;
        }

        nextResponder?.becomeFirstResponder();
        return false;
    }
    if (textField.text?.characters.count >= 1  && string.characters.count == 0){
        // on deleteing value from Textfield
        let presentTag = textField.tag;
        // get next responder
        var presentResponder = textField.superview?.viewWithTag(presentTag);

        if (presentResponder == nil){
            presentResponder = textField.superview?.viewWithTag(1);
        }
        textField.text = "";
        presentResponder?.becomeFirstResponder();
        return false;
    }

    let currentCharacterCount = textField.text?.characters.count ?? 0
    let newLength = currentCharacterCount + string.characters.count - range.length
    if newLength > 1 {
        textField.text = string
        if (nextResponder != nil){
            nextResponder?.becomeFirstResponder();
        }

    }
    let returnVal = newLength <= 1
    return returnVal;
}
like image 57
user2604897 Avatar answered Aug 11 '26 02:08

user2604897



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!