Swift TextFieldで時刻入力のチェック処理


概要

TextFieldで時刻入力を求めるインターフェースのチェック処理。TextFieldプロパティとdelegateに以下の処理を記述した。

  1. 入力キーボードは数字のみ
  2. 5桁目の入力は切り捨てる。常に0〜4桁のみ表示
  3. 1桁目が3〜9の場合、"03"〜"09"のように頭に0を補完
  4. 2桁目までが24以上の場合、エラーとしてborderとtextを赤で表示
  5. 3桁目が6〜9の場合、"06"〜"09"のように頭に0を補完
  6. エラー時または、入力値が4桁未満の場合、完了ボタンをdisableにする
f:id:letitride:20190822110404p:plainf:id:letitride:20190822110419p:plain


キーボードを数字のみとする

keyboardType.numberPadを指定することで数字のみのキーボードを表示できる。

self.timeTextField = UITextField()
self.timeTextField.delegate = self
self.timeTextField.keyboardType = .numberPad


Delegateの処理

shouldChangeCharactersInで入力検知時に(2)〜(6)までの処理を記述する

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    guard let value = textField.text else{
        return true
    }
    
    var error = false
    func errorText(){
        error = true
        textField.textColor = UIColor.red
        textField.layer.borderWidth = 1.0
        textField.layer.borderColor = UIColor.red.cgColor
    }
    
    func normalText(){
        textField.textColor = UIColor.black
        textField.layer.borderWidth = 0
    }

    //完了ボタンを非活性に
    self.doneButton.isEnabled = false
   //一旦、エラーなしにカラーを初期化
    normalText()

    //入力済みテキストと新たに入力されたcharacterを結合したものが評価対象の入力値となる
    var fullValue = value + string
    //新たに入力されたcharacterが```""(空文字)```の場合、deleteキーが押下。よって1文字削除
    if(string == ""){
        fullValue = String(fullValue.prefix(fullValue.count - 1))
    }
    
    //未入力時は完了を受け付ける(ここは好みで)
    if fullValue.count == 0{
        self.doneButtonItem.isEnabled = true
        self.doneButtonItemByKeyboard.isEnabled = true
    }
    
    //1桁目が3以上の場合、"03"〜"09"のように頭に0を補完
    if fullValue.count == 1 {
        let h = Int(fullValue.prefix(1))
        if h! > 2 {
            textField.text = "0"
        }
    }
    
    //2桁目までが24以上の場合、エラーとしてborderとtextを赤で表示
    if fullValue.count >= 2 {
        let h = Int(fullValue.prefix(2))
        if h! > 23 {
            errorText()
        }
    }
    
    //3桁目が6以上の場合、"06"〜"09"のように頭に0を補完
    if fullValue.count == 3 {
        let minute = Int(fullValue.suffix(1))
        if minute! > 5 {
            textField.text = textField.text! + "0"
        }
    }
    
    //4桁以上の入力があった場合、4桁目と5桁目の入力を入れ替える
    if fullValue.count >= 4 {
        let time = String(fullValue.prefix(4))
        textField.text = String(time.prefix(3))
        let minute = Int(time.suffix(2))
        //下2桁が60以上の場合はエラー
        if minute! > 59 {
            errorText()
        }else{
            //4桁入力でエラーがない場合、完了ボタンを活性化
            if(error == false){
                self.doneButton.isEnabled = true
            }
        }
    }
    return true
}