I had solved this problem using below approach :
Four text-field with 1st and 2nd one read-only. In third textfield I’ve placed label with two encrypted value (i.e. XX) and third textfield accepts two digits only. The fourth textfield accepts four digits.
Note : I’ve used this label and textfield approach because I’ve credit/debit card number (14 digit) already from DB or other source. I need to accept only last 6 digit from user and compare with existing value.
When user enters two digits in third textfield then it automatically jumps to fourth textfield. Thereafter when user enters four digit in 4th textfield then it automatically jumps to Expiry month textfield followed by Expiry year.
setBorderColor
function sets only bottom border color to Expiry month and Year textfield.
I’ve added UIToolbar with done button
to numeric keypad (set during design time) for all textfield.

Below is code that I’ve used :
@IBOutlet weak var txtCardDetails1: UITextField!
@IBOutlet weak var txtCardDetails2: UITextField!
@IBOutlet weak var txtCardDetails3: UITextField!
@IBOutlet weak var txtCardDetails4: UITextField!
@IBOutlet weak var txtExpiryMonth: UITextField!
@IBOutlet weak var txtExpiryYear: UITextField!
let objBlackColor = UIColor.blackColor()
let objGreyColor = UIColor.grayColor()
override func viewDidLoad() {
super.viewDidLoad()
//Add done button to numeric pad keyboard
let toolbarDone = UIToolbar.init()
toolbarDone.sizeToFit()
let barBtnDone = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.Done,
target: self, action: #selector(VerifyCardViewController.doneButton_Clicked(_:)))
toolbarDone.items = [barBtnDone] // You can even add cancel button too
txtCardDetails3.inputAccessoryView = toolbarDone
txtCardDetails4.inputAccessoryView = toolbarDone
txtExpiryMonth.inputAccessoryView = toolbarDone
txtExpiryYear.inputAccessoryView = toolbarDone
// Set an action on EditingChanged event of textfield
txtCardDetails3.addTarget(self, action: #selector(VerifyCardViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)
txtCardDetails4.addTarget(self, action: #selector(VerifyCardViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)
txtExpiryMonth.addTarget(self, action: #selector(VerifyCardViewController.textFieldDidChange(_:)), forControlEvents: UIControlEvents.EditingChanged)
setBorderColor(txtExpiryMonth,setBorderColor: objGreyColor)
setBorderColor(txtExpiryYear,setBorderColor: objGreyColor)
}
//Set bottom border color to textfield
func setBorderColor(objTextField : UITextField, setBorderColor objColor:UIColor) {
let bottomLine = CALayer()
bottomLine.frame = CGRectMake(0.0, objTextField.frame.height - 1, objTextField.frame.width, 1.0)
bottomLine.backgroundColor = objColor.CGColor
objTextField.borderStyle = UITextBorderStyle.None
objTextField.layer.addSublayer(bottomLine)
}
func doneButton_Clicked(sender: AnyObject) { // Hide keyboard when done button is clicked
txtCardDetails3.resignFirstResponder()
txtCardDetails4.resignFirstResponder()
txtExpiryMonth.resignFirstResponder()
txtExpiryYear.resignFirstResponder()
}
func textFieldDidChange(textField: UITextField){ // Change text focus as per condition
let text = textField.text
if textField.tag == 101 { // Set tag to textfield (if multiple) during design time
if text?.utf16.count==2 {
txtCardDetails4.becomeFirstResponder() // Move to next text field
}
}
else if textField.tag == 102 {
if text?.utf16.count==4 {
txtExpiryMonth.becomeFirstResponder()
}
}
else if textField.tag == 103 {
if text?.utf16.count==2 {
txtExpiryYear.becomeFirstResponder()
}
}
}
func textFieldDidBeginEditing(textField: UITextField) {
if textField.tag == 103 { // Set border color based on focus
setBorderColor(txtExpiryMonth,setBorderColor: objBlackColor)
}
else if textField.tag == 104 {
setBorderColor(txtExpiryMonth,setBorderColor: objBlackColor)
}
textField.becomeFirstResponder()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true;
}
//User can enter two digits in textfield with tag 101, 103, 104 and four digits in textfield with tag 102
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text {
let newStr = (text as NSString)
.stringByReplacingCharactersInRange(range, withString: string)
if newStr.isEmpty {
return true
}
let intvalue = Int(newStr)
if textField.tag == 101 || textField.tag == 103 || textField.tag == 104{
return (intvalue >= 0 && intvalue <= 99) ? true : false
}
else if textField.tag == 102 {
return (intvalue >= 0 && intvalue <= 9999) ? true : false
}
}
return true
}