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
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With