テキストフィールドでバリデーションに引っかかったときに文字色を赤くし、下線を引く


こんにちは

こんな感じの↓テキストフィールドを作ってみました。

コード

UITextField を継承したクラスに isValid を持たせる形でやってみました。

import UIKit

class FormTextField: UITextField {
    private var validatorLayer: CALayer!

    var isValid = true {
        didSet {
            validatorLayer.isHidden = isValid
            validatorLayer.frame = CGRect(x: 0, y: self.frame.height - 2, width: self.frame.width, height: 2)
            textColor = isValid ? .black : .red

        }
    }

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

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        didInit()
    }

    private func didInit() {
        // バリデーション用の下線
        validatorLayer = CALayer()
        validatorLayer.backgroundColor = UIColor.red.cgColor
        validatorLayer.isHidden = true
        layer.addSublayer(validatorLayer)
    }

}

Storyboard でテキストフィールドを設定している場合はクラス名を FormTextField にしておくのを忘れずに!

これで

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textField: FormTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        textField.addTarget(self, action: #selector(handleTextField(_:)), for: .editingChanged)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func handleTextField(_ textField: FormTextField) {
        // バリデーション例として20文字以内であるかチェック
        guard let text = textField.text else { return }
        textField.isValid = text.characters.count < 20
    }

}

でOKです!

サンプル

サンプルはこちらです!
https://github.com/keisei1092/FormFieldPractice