简体   繁体   中英

Swift : Encrypted input for UITextField for Card details

I want to accept Card details as input from user . The condition is that first 10 character will be hidden where as user will be allowed to enter next 6 character.

I've used four text field for this (my assumption). Any other suggestion is welcome.

Q.1. How to allow user to enter directly from 11th character in 3rd text field?

For Expiry Date field I've used two text field.

Q.2. How to make text field only have border in bottom (no left,right and top border)?

在此输入图像描述

Q.1. How to allow user to enter directly from 11th character in 3rd text field?

A-1 : txt3.becomeFirstResponder()

Q.2. How to make text field only have border in bottom (no left,right and top border)?

A-2 : Use below line of code:

 func addbottomBorderWithColor(view : UIView, color: UIColor, width: CGFloat) {
        let border = CALayer()
        border.backgroundColor = color.CGColor
        border.frame = CGRectMake(15.0, view.frame.size.height-width, view.frame.size.width,width )
        view.layer.addSublayer(border)
    }

I had solved this problem using below approach :

  1. Four text-field with 1st and 2nd one read-only. In third textfield I've placed label with two encrypted value (ie 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.

  2. setBorderColor function sets only bottom border color to Expiry month and Year textfield.

  3. 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
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM