【Swift】UITextFieldのキーボードを閉じる方法

UITextFieldに入力時、キーボードタイプをNumber PadにするとReturnキーが無くて`textFieldShouldReturn`で閉じることが出来なくて困ったのでキーボードを閉じる方法を調べました。

##キーボードを閉じる方法　その①

`UITextFieldDelegate`の`textFieldShouldReturn`にキーボードを閉じる処理を書いて、キーボードのリターンキーを押すとキーボードが閉じてくれる方法

```swift
 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
```

###その方法で困った事

キーボードタイプがNumber Padだとリターンキーが無くて困った。
`textFieldShouldReturn`が使えないじゃないか、、、

<img width="300" alt="numberpadWithDone" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678954/b519c8c7-5a50-09e9-1727-bc876ad174f5.png">

##キーボードを閉じる方法　その②
`InputAccesoryView`に完了ボタンを追加して、ボタンをトリガーにしてキーボードを閉じてもらう方法

<img width="300" alt="numberpad" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678954/b641846e-40e4-c5fe-c61b-06e59ec0d7ae.png">

こんな感じでキーボード上に完了ボタンを出現させる。

```swift:
@IBOutlet weak var numberPadTextField: UITextField!

override func viewDidLoad() {
        super.viewDidLoad()
        
        //inputAccesoryViewに入れるtoolbar
        let toolbar = UIToolbar()
        
        //完了ボタンを右寄せにする為に、左側を埋めるスペース作成
        let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
                                    target: nil,
                                    action: nil)
        //完了ボタンを作成
        let done = UIBarButtonItem(title: "完了",
                                   style: .done,
                                   target: self,
                                   action: #selector(didTapDoneButton))
        
        //toolbarのitemsに作成したスペースと完了ボタンを入れる。実際にも左から順に表示されます。
        toolbar.items = [space, done]
        toolbar.sizeToFit()
        
        //作成したtoolbarをtextFieldのinputAccessoryViewに入れる
        numberPadTextField.inputAccessoryView = toolbar
        
        //キーボードタイプを番号のみに指定
        numberPadTextField.keyboardType = .numberPad
    }
    
    //完了ボタンを押した時の処理
    @objc func didTapDoneButton() {
        numberPadTextField.resignFirstResponder()
    }
```

##キーボードを閉じる方法　その③
ViewControllerにTap Gesture Recognizerを配置して、画面をタップされたらキーボードを閉じる方法

####1.`Tap Gesuture Recognizer`を`ViewController`に配置
<img width="600" alt="tapgesture" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678954/280c46e6-1ce8-0002-7778-3c22b0becd7e.png">

####2.`Tap Gesuture Recognizer`を`control` + ドラッグで`ViewController`と紐付け
<img width="300" alt="tapgesture2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678954/90ce08b2-5b8d-8ebe-0c16-9bfa1b68453e.png">

####3.紐付けしたTap Actionにキーボードを閉じる処理を書く
```swift
@IBAction func didTapView(_ sender: UITapGestureRecognizer) {
        //キーボードを閉じる処理
        view.endEditing(true)
    }
```

なんで`view.endEditing(true)`がキーボードを閉じてくれるのか？

公式ドキュメントより引用
>Causes the view (or one of its embedded text fields) to resign the first responder status.

>ビュー（またはその埋め込みテキストフィールドの1つ）にファーストレスポンダーステータスを辞任させます。

ということで`view.endEditing()`の引数に<b><font color="red">true</font></b>を入れると、キーボードが現れている場合は`textField.resignFirstResponder()`してくれるのでキーボードを閉じてくれます。

##キーボードを閉じる方法　その④
その③の画面タップという方法は同じですが、実装がスマートなパターン

`Tap Gesture Recognizer`を配置したり、ファイルに紐付けたりしなくて良いです。

これを宣言するだけ。

```swift
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        view.endEditing(true)
    }
```

##サンプルデモ
キーボード上の`inputAccesoryView`の完了ボタンと画面タップでキーボードを閉じています。
![イメージ.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678954/7f2e06f2-1783-1031-b6e7-8120f2fa7fd4.gif)

##まとめ
些細なことから調べ出したら色んな方法を知ることが出来た。
これも参考にさせてもらった記事のおかげです。
ありがとうございました。
是非、参考元の記事も見に行ってみてください☺︎

また何か間違いやより良い方法がありましたら、優しく教えていただけると幸いです🙇‍♂️

##参考
<a href="https://qiita.com/mkns/items/8f823e039022e801749e">UTextFieldのソフトキーボードを数値のみにして完了ボタンを追加する</a>
<a href="https://qiita.com/og_omochi/items/f2d5e8cb35e3b7091942">[Swift]キーボード以外をタッチするとキーボードが下がる方法</a>
<a href="https://developer.apple.com/documentation/uikit/uiview/1619630-endediting">Apple公式ドキュメント: endEditing(_:)</a>