1

Here is the result I want to achieve

I am now working on a UITextfield. I hope to know how to add four discontinuous bottom border to a UITextfield, and how to make the space between input digits larger to make them fit exactly on the four lines respectively. Moreover, if possible, how to make the line become black (while other lines remain grey) when users are inputing digit on that line? Thank you so much!

RajeshKumar R
  • 15,445
  • 2
  • 38
  • 70
Kevin
  • 23
  • 3

2 Answers2

0

check this.. enter image description here

ViewController.swift

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var txtOne: UITextField!
    @IBOutlet weak var txtTwo: UITextField!
    @IBOutlet weak var txtThree: UITextField!
    @IBOutlet weak var txtFour: UITextField!

    @IBOutlet weak var vwFour: UIView!
    @IBOutlet weak var vwThree: UIView!
    @IBOutlet weak var vwTwo: UIView!
    @IBOutlet weak var vwOne: UIView!


    func textFieldDidBeginEditing(_ textField: UITextField) {
        if textField == txtOne {
            vwOne.backgroundColor = .black
            vwTwo.backgroundColor = .lightGray
            vwThree.backgroundColor = .lightGray
            vwFour.backgroundColor = .lightGray
        } else if textField == txtTwo {
            vwTwo.backgroundColor = .black
            vwOne.backgroundColor = .lightGray
            vwThree.backgroundColor = .lightGray
            vwFour.backgroundColor = .lightGray
        } else if textField == txtThree {
            vwThree.backgroundColor = .black
            vwTwo.backgroundColor = .lightGray
            vwOne.backgroundColor = .lightGray
            vwFour.backgroundColor = .lightGray
        } else {
            vwFour.backgroundColor = .black
            vwTwo.backgroundColor = .lightGray
            vwThree.backgroundColor = .lightGray
            vwOne.backgroundColor = .lightGray
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

}
Ben Rockey
  • 920
  • 6
  • 23
0

Use following subclass of UITextField and create textfield for each digit either in storyboard or programatically.

Note that each textfield has to set a tag, such as

1st Digit: textField1.tag=1

2nd Digit: textField1.tag=2

3rd Digit: textField1.tag=3

4th Digit: textField1.tag=4

class CustomTextField: UITextField {
    private let normalStateColor = UIColor.lightGray.cgColor
    private let focusStateColor = UIColor.black.cgColor

    private let border = CALayer()
    private let borderHeight: CGFloat = 4.0

    // MARK:- Init
    required init?(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
        setup()
    }

    override init(frame:CGRect) {
        super.init(frame:frame)
        setup()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        setup()
    }
    // MARK:- Overrides
    override func layoutSubviews() {
        super.layoutSubviews()

        let size = self.frame.size
        self.border.frame = CGRect(x: 0, y: size.height - borderHeight, width: size.width, height: borderHeight)
    }

    override func willMove(toSuperview newSuperview: UIView!) {
        guard newSuperview != nil else {
            NotificationCenter.default.removeObserver(self)
            return
        }

        NotificationCenter.default.addObserver(self, selector: #selector(beginEdit),
                                               name: UITextField.textDidBeginEditingNotification, object: self)
        NotificationCenter.default.addObserver(self, selector: #selector(endEdit),
                                               name: UITextField.textDidEndEditingNotification, object: self)
    }

    @objc func beginEdit() {
        border.backgroundColor = self.focusStateColor
    }

    @objc func endEdit() {
        border.backgroundColor = self.normalStateColor
    }

    private func setup() {
        border.backgroundColor = self.normalStateColor
        textAlignment = .center
        borderStyle = .none
        layer.addSublayer(border)
        delegate = self
    }
}

extension CustomTextField: UITextFieldDelegate {

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField.text!.count < 1  && string.count > 0 {
            textField.text = string
            textField.superview?.viewWithTag(textField.tag + 1)?.becomeFirstResponder()
            return false
        } else if textField.text!.count >= 1  && string.count == 0 {
            textField.text = ""
            textField.superview?.viewWithTag(textField.tag - 1)?.becomeFirstResponder()
            return false
        }

        return true
    }
}

That yields

enter image description here

AamirR
  • 11,672
  • 4
  • 59
  • 73
  • I shoule make a textfield for each of the digit (which means four digits in total) or just one textfield for all digits? – Kevin May 21 '19 at 20:07
  • a textfield for each of the digit, you can download the sample project and check Main.storyboard – AamirR May 21 '19 at 20:16
  • Thank you! And where can I set tags for textfields? – Kevin May 21 '19 at 20:57
  • either in storyboard (attributes inspector) or in `viewDidLoad` – AamirR May 21 '19 at 20:59
  • Can I declare the four textfields as textField1, textField2, textField3, textField4, and in viewDidLoad write textField1.tag=1, txtField2.tag=2, etc. Will that work? – Kevin May 21 '19 at 21:19
  • Hi, I tried your method for several times, but it still doesn't work. I wonder where I did wrong. I use your CustomTextField.swift and put all four textfields like @IBOutlet weak var TextField1: CustomTextField!, IBOutlet weak var TextField2: CustomTextField!, etc. And the outcome is just four seperate textfields with no underline borders, and neither of them has single-digit limit. Is there any problem with my above code? – Kevin May 25 '19 at 05:01
  • How can I check your code, post it some where (dropbox, drive) and send me the link – AamirR May 25 '19 at 05:14
  • Here is the link https://github.com/reallljanice/Verification-Text-Field. Thank you so much for your help! – Kevin May 25 '19 at 16:01
  • You changed UITextField class to `VerificationTextField`. You also need to change the **Custom Class** in Main.storyboard, select all textFields and go to **Identity Inspector** and change the class from CustomTextField to `VerificationTextField` – AamirR May 25 '19 at 17:16