【Swift5】iOS14のUIDatePickerとUILabelを組み合わせて日付選択ボタンを作る

# 概要
DatePicker だけで日付選択をかっこよく、かつ楽に実装しようとしたところ
デザインがうまいこといかなかった際の試行錯誤を備忘録として残す。
ゴリ押し実装なので軽い気持ちでみてください。

# この記事の完成品
日付のラベル部分を押すとカレンダーから日付が選べる
選択が終わるとアニメーションしながら画面が閉じてラベル部分に日付が適応される

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204184/e82fcfbb-4e63-7daa-cebb-770112674414.gif" width="300px"/>

# やりたかったこと
`---年-月-日`と表示されている日付をタップするとiOS14のカレンダー式日付選択画面が表示される。
デザインはこんな感じ

選択前
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204184/3ebb806c-59bf-6dd3-adb9-335026e7101d.jpeg" width="600px"/>
選択後
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204184/c98c39d2-ebfa-8a65-6fca-42c776345421.jpeg" width="600px"/>

なんかiOS14からDatePickerの挙動がかっこよくなったのでそれを使えば簡単だろうと思っていました。

iOS14のDatePicker関連の記事はこちら
https://qiita.com/kj_trsm/items/a53b0b3f7e1bc7c06106

# Try & Error

## 1:何も考えずUIButtonを置いてみた
ボタンを置いてデザインを合わせるも、いやいやDatePicker呼べないじゃんってなった（ColorPickerみたいに使うと思ったら違った）
カラーピッカーはこちら
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204184/3ebb806c-59bf-6dd3-adb9-335026e7101d.jpeg

## 2:DatePickerを置いてみる
上に書いた記事にもあるが、Styleがいくつかある
今回のデザインに近いであろう

```Hoge.swift
datePicker.preferredDatePickerStyle = .compact
datePicker.datePickerMode = .date
```

見た目はこんな感じ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204184/66f11d92-b398-35c5-d4c9-b9e5fa660274.jpeg" width="600px"/>!

挙動は希望通りなのであとはデザイン調整だ！っという気持ちになるが・・・
デザイン変更が上手いこといかない

- 背景色のグレーはなんだ？ --> `datePicker.backgroundColor = .clear` にするも、変化なし
- 文字を左揃えにしたい --> UILabel みたいな設定が見つからない
- `----年-月-日`という形式で表示させるのどうやるの？

# 解決方法

`背景色のグレーはなんだ？`

```Hoge.swift
datePicker.subviews[0].subviews[0].subviews[0].backgroundColor = .clear
```
で背景色が変えられた

`文字を左揃えにしたい`
-> 分からん、無理だった

文字の左揃えができなかったので、ゴリ押しでUILabelの上にUIDatePickerを重ねることに
重ねた上で

```Hoge.swift
datePicker.subviews.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })
```

でdatePickerのSubViewsを消去することで謎のグレー背景も、日付の文字も消える。
重ねた下にあるUILabelの文字を、あたかもUIDatePickerの文字のように表示させる
そうすることでタップ時にはUIDatePickerが動作、表示する日付はUILabelとなり、簡単に希望通りの動作を作れた。

`UIDatePicker で ----年-月-日 という形式で表示させるのどうやるの？`
-> UILabelに表示させることにしたので調査してません

# 完成形

StoryboardでUILabelとUIDatePickerを重ねて、UILabelに`---年-月-日`と設定
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204184/20343c84-d0f2-59d1-4736-327d1d559611.png" width="600px"/>

```HogeViewController.swift 

import UIKit
import RxSwift
import RxCocoa

class HogeViewController: UIViewController {

    @IBOutlet var datePicker: UIDatePicker!
    @IBOutlet var dateLabel: UILabel!

    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        datePicker.rx.value.changed.asObservable()
            .subscribe(onNext: { date in
                self.dateLabel.text = date.toDisplayString()
            }
            .disposed(by: disposeBag)
    }

    override func viewDidLayoutSubviews() {
        // datePicker を透明にする
        datePicker.subviews.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })
    }
}
```
適当に`datePicker`の値の変更を監視してUILabelに日付として設定させれば完成
タップしたら値が設定され、閉じる時のアニメーションも勝手にDatePickerがやってくれた

# おわりに
結局重ねるというオチになってしまった。
きっともっとちゃんとした解決策がありそうだけど備忘録として残しておきます。