0

I have 4 UITextFields in one UIView like this:

enter image description here

each UITextField limited to 4 characters. i want implement a auto switching between UITextFields with count characters of each UITextField.

i use shouldChangeCharactersIn for limitation characters:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let maxLength = 4
        var newString = String()
        let currentString: NSString = textField.text! as NSString
        newString = currentString.replacingCharacters(in: range, with: string)

        return newString.length <= maxLength
    }

and this is my switching implement:

func textFieldDidChange(_ textField: UITextField){

    let text = textField.text

    if text?.utf16.count == 4 {
        switch textField {
        case firstPartTextField:
            secondPartTextField.becomeFirstResponder()
        case secondPartTextField:
            thirdPartTextField.becomeFirstResponder()
        case thirdPartTextField:
            fourthPartTextField.becomeFirstResponder()
        default:
            break
        }
    }
}

my problem is switch to previous UITextField in deleting texts, i can not detect backSpace event when UITextField is empty.

  • (1) [Not all credit cards are 16-digit long](http://stackoverflow.com/a/19161529/224671) (2) Maybe you could use [existing](https://github.com/3lvis/FormTextField) [libraries](https://stripe.github.io/stripe-ios/docs/Classes/STPPaymentCardTextField.html) instead of inventing your own. – kennytm Jan 28 '17 at 17:43
  • Try this answer, this worked for me http://stackoverflow.com/a/39483754/6245319 – Mohsen Hosseinpour Jan 28 '17 at 19:55
  • 1
    i personally don't like to input a number into 4 seperate textfields :( – muescha Jan 29 '17 at 03:48
  • for example pasting creditcard from my 1Password is not possible with this 4 Textfields :( – muescha Jan 29 '17 at 03:49

2 Answers2

1

Add target for textField in viewDidLoad()

firstTxt.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
    secTxt.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
    thirdTxt.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)
    fourTXt.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControlEvents.editingChanged)

Than create selector method

func textFieldDidChange(textField: UITextField){

    let text = textField.text

    if text?.utf16.count == 1{
        switch textField{
        case firstTxt:
            secTxt.becomeFirstResponder()
        case secTxt:
            thirdTxt.becomeFirstResponder()
        case thirdTxt:
            fourTXt.becomeFirstResponder()
        case fourTXt:
            fourTXt.resignFirstResponder()
        default:
            break
        }
    }else{

    }
}
rptwsthi
  • 10,094
  • 10
  • 68
  • 109
AbhiRaz
  • 132
  • 2
  • 12
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – thewaywewere Jun 19 '17 at 06:58
  • As above each UITextField had a selector which call by self and when the text will change it will count the character and when it comes true to the condition it will change to next UITextField – AbhiRaz Nov 22 '19 at 07:52
0

Make an outlet collection of all your textfields and configure them like so:

OutletCollection:
@IBOutlet var textfields: [UITextField]!
Add this in viewDidLoad:
for (i, tf) in textfields.enumerated() {
    tf.layer.cornerRadius = 5
    tf.clipsToBounds = true
    tf.tag = i
    tf.delegate = self
}

In the target function, you'll restrict the count in this manner:

func textFieldDidChange(textField: UITextField) {
       let text = textField.text!
       if text.utf16.count >= 4 {
           if textField.tag < 4 {
               codeTextfields[textField.tag + 1].becomeFirstResponder()
           }
           else {
               textField.resignFirstResponder()
           }
       }
}

This will the change in one of your delegate methods:

func textFieldDidBeginEditing(_ textField: UITextField) {
        textField.text = ""
}

Refined version of the following answer: How to move cursor from one text field to another automatically in swift ios programmatically?

CoderSulemani
  • 123
  • 11