slysid
slysid

Reputation: 5488

UITextField Delegate "shouldChangeCharactersIn" not called for first entry in textfield

I am building a view which accepts 4 digit OTP. The code I have is as follows

"CodeText" is subclass of UITextField

    class RegisterController: ModelController, UITextFieldDelegate {

    @IBOutlet var firstDigit:CodeText?
    @IBOutlet var secondDigit:CodeText?
    @IBOutlet var thirdDigit:CodeText?
    @IBOutlet var fourthDigit:CodeText?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationItem.hidesBackButton = true
        self.firstDigit!.delegate = self
        self.secondDigit!.delegate = self
        self.thirdDigit!.delegate = self
        self.fourthDigit!.delegate = self

        self.firstDigit!.becomeFirstResponder()
    }


    // UITextField Delegate Methods

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {


        if (textField == self.firstDigit) {

            if(textField.text!.characters.count >= 1 ) {

                self.secondDigit?.becomeFirstResponder()
            }
        }
        else if (textField == secondDigit) {

            if(textField.text!.characters.count >= 1 ) {

                self.thirdDigit?.becomeFirstResponder()
            }

        }
        else if (textField == thirdDigit) {

            if(textField.text!.characters.count >= 1 ) {

                self.fourthDigit?.becomeFirstResponder()
            }
        }
        else if (textField == fourthDigit) {

            print("Fourth Digit")

            if(textField.text!.characters.count >= 1 ) {

                self.fourthDigit?.resignFirstResponder()
            }
        }

        return true
    }
}

Above code works fine for me except for one feature. I want the keyboard to be dismissed after fourth digit entry, but what's happening is the "shouldChange" delegate method is not called when the "fourthDigit" get it's focus and get it's first entry but the delegate is called when the textfield gets it's second entry and the keyboard is getting dismissed.

So in order to get the keyboard dismissed an unnecessary keystroke is needed.

Any suggestion would be helpful

Upvotes: 0

Views: 3891

Answers (2)

Pratik Jamariya
Pratik Jamariya

Reputation: 820

Please try string.length>0 instead of textField.text!.characters.count >= 1

EDIT

I've managed to get callback when user enters a character in textfield using a notification

// in your respective method where you init your text field
[_txtSearchLocation addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

- (void)textFieldDidChange :(UITextField *) textField{
}

When this method gets call you can call textField.resignFirstResponder

Sorry for Obj-c, i copied this from my current open file thx

Upvotes: 0

Anbu.Karthik
Anbu.Karthik

Reputation: 82759

alternate choice for capture all event of your text field, with out coding

  • Cretae a IBAction (in your Current textfield VC)
  • Ctrl-Click (or right click) on the UITextField in Interface Builder
  • Connect the "Editing Changed" event to the File's Owner's IBAction added in the first step.

for e.g your UIControlEventEditingChanged method name is updateContentsOfTextField

and get output in

func updateContentsOfTextField(_ theTextField: UITextField) {
print("text changed: \(theTextField.text)")
}

you can get the more information from here

Upvotes: 2

Related Questions