cs4alhaider
cs4alhaider

Reputation: 1446

How to move to the next UITextField automatically in Swift

I have 2 textFields with NumberPad keyboard type

@IBOutlet weak var ourTextField: UITextField!
@IBOutlet weak var forThemTextField: UITextField!

and I want to automatically move to the other textfield (from ourTextField to forThemTextField) after entering two numbers inside the ourTextField then after going to the other textfield (forThemTextField) and entering 2 numbers I want the keyboard hide automatically

I have added a condition to only accept two numbers in my textFields by this code :

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let lengthsDictionary = [ourTextField : 2, forThemTextField: 2]
    guard let length = lengthsDictionary[textField] else {
        return true
    }
    let currentCharacterCount = textField.text?.count ?? 0
    if (range.length + range.location > currentCharacterCount){
        return false
    }
    let newLength = currentCharacterCount + string.count - range.length

    return newLength <= length
}

Upvotes: 3

Views: 7053

Answers (3)

Jack
Jack

Reputation: 14329

Use shouldChangeCharactersIn of UITextFieldDelegate method & listen with keyboard string
Use tag of textFields, like tag 1 & tag 2

as

class TestingViewController: UIViewController{
    @IBOutlet weak var firstTextField: UITextField!
    @IBOutlet weak var secondTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        firstTextField.delegate = self
        secondTextField.delegate = self
        firstTextField.tag = 1
        secondTextField.tag = 2
        firstTextField.keyboardType = .numberPad
        secondTextField.keyboardType = .numberPad
    }
}

extension TestingViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return textField.shouldChangeCustomOtp(textField: textField, string: string)

    }
}

extension UITextField {
    func shouldChangeCustomOtp(textField:UITextField, string: String) ->Bool {

        //Check if textField has two chacraters
        if ((textField.text?.count)! == 1  && string.count > 0) {
            let nextTag = textField.tag + 1;
            // get next responder
            var nextResponder = textField.superview?.viewWithTag(nextTag);
            if (nextResponder == nil) {
                nextResponder = textField.superview?.viewWithTag(1);
            }

            textField.text = textField.text! + string;
            //write here your last textfield tag
            if textField.tag == 2 {
                //Dissmiss keyboard on last entry
                textField.resignFirstResponder()
            }
            else {
                ///Appear keyboard
                nextResponder?.becomeFirstResponder();
            }
            return false;
        } else if ((textField.text?.count)! == 1  && string.count == 0) {// on deleteing value from Textfield

            let previousTag = textField.tag - 1;
            // get prev responder
            var previousResponder = textField.superview?.viewWithTag(previousTag);
            if (previousResponder == nil) {
                previousResponder = textField.superview?.viewWithTag(1);
            }
            textField.text = "";
            previousResponder?.becomeFirstResponder();
            return false
        }
        return true

    }

}

Output:

enter image description here

Upvotes: 6

Manish
Manish

Reputation: 184

In viewDidLoad :- 

ourTextField?.addTarget(self, action: #selector(CalculatorViewController.textFieldDidChange(_:)), for: UIControlEvents.editingChanged)

forThemTextField?.addTarget(self, action: #selector(CalculatorViewController.textFieldDidChange(_:)), for: UIControlEvents.editingChanged)


//create function

func textFieldDidChange(_ textField: UITextField) {
        if textField == ourTextField {
            if (textField.text.count)! >= 2 {
                forThemTextField?.becomeFirstResponder()
            }
        }
        else if textField == forThemTextField {
            if (textField.text?.count)! >= 2 {
                forThemTextField.resignFirstResponder()
            }
        }
    }

Upvotes: 4

Paul
Paul

Reputation: 710

Add target to the UITextField (in viewDidLoad()), for example:

mTfActuallyFrom?.addTarget(self, action: #selector(CalculatorViewController.textFieldDidChange(_:)), for: UIControlEvents.editingChanged)

In the delegate function, use UITextField.becomeFirstResponder() to move the focus to the next textfield. Change your conditions to your requirement. For example:

func textFieldDidChange(_ textField: UITextField) {
        if textField == mTfActuallyFrom {
            if (textField.text?.characters.count)! >= 4 {
                mTfActuallyTo?.becomeFirstResponder()
            }
        }
        else if textField == mTfActuallyTo {
            if (textField.text?.characters.count)! >= 4 {
                dismissKeyboard(gesture: nil)
            }
        }
    }

Upvotes: 2

Related Questions