iOS14でのDatePickerの挙動について（SwiftUI)

#iOS14でのDatePickerの挙動について（SwiftUI)

前回書かせていただいたiOS14(UIKit)でのDatePickerに関してですが、ついでにSwiftUIでも調べたので書かせていただきました。
今回は従来のものから何が追加さたのかというところと実際の使い方のCodeも載せておきます。

## 環境
macOS Catalina 10.15.6
Xcode Version 12.0.1

## はじめに
まずはじめにSwiftUIでのDatePickerの使い方から


```swift

struct ContentView: View {
    @State private var selectionDate = Date()
    var body: some View {
        DatePicker("タイトル",
                   selection: $selectionDate)
    }
}

```

これだけでDatePicerを使うことができます。
さすがSwiftUI！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/df364c4d-c928-b3a0-57af-c6daec7c0eef.png" width="300">

デフォルトだとこんな感じです。
これだと流石に使い物にならんのでちょっと修正を加えます



```swift
struct ContentView: View {
    @State private var selectionDate = Date()
    var body: some View {
        DatePicker("タイトル",
                   selection: $selectionDate)
            // これを入れることによってラベルを表示させなくします。
            .labelsHidden()
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/ca279b05-f2ca-8208-17d6-891ef83c68a7.png" width="300">

これで一旦検証はできそうです。

ちなみに別途Pickerの上にタイトルを入れたい場合

```swift
struct ContentView: View {
    @State private var selectionDate = Date()
    var body: some View {
        VStack {
            Text("タイトル")
                .font(.title)
            DatePicker("タイトル",
                       selection: $selectionDate)
                .labelsHidden()
            
        }
    }
}
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/32b780b9-a0fb-a20e-5e36-79ca2eb42f20.png" width="300">

このようにすることでタイトルを付けれるようになります。
他にも良い実装はありますが今回は割愛します。

## 本題
では実際にSwiftUIではどのようにしてStyleやModeを変更するか確認します。

まずUIKitではenumで新しく定義されていました。

```swift
public enum UIDatePickerStyle : Int {
    case automatic = 0
    case wheels = 1
    case compact = 2

    @available(iOS 14.0, *)
    case inline = 3
}
```

swiftUIではまずこのように定義してあります。

```swift
extension View {
    /// Sets the style for date pickers within this view.
    @available(tvOS, unavailable)
    @available(watchOS, unavailable)
    public func datePickerStyle<S>(_ style: S) -> some View where S : DatePickerStyle
}

```

使い方としましては、

```swift
DatePicker("タイトル", selection: $selectionDate)
    .datePickerStyle(CompactDatePickerStyle())
```

このように定義することでStyleの変更ができます。

## Style

公式ドキュメントを見るといくつかStyleがあります。

```swift
struct DefaultDatePickerStyle
struct CompactDatePickerStyle
struct WheelDatePickerStyle
struct FieldDatePickerStyle
struct StepperFieldDatePickerStyle
struct GraphicalDatePickerStyle
```

この中の

>FieldDatePickerStyle
StepperFieldDatePickerStyle

この二つは　macOS 10.15でのみ使えるとのことです。

iOS14で追加されたものは

> GraphicalDatePickerStyle

になります。

> DefaultDatePickerStyle
CompactDatePickerStyle
WheelDatePickerStyle


こちらの3つはiOS 13.0から追加されたものになります。

では実際の表示を確認してみます。



- DefaultDatePickerStyle

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/35ee1611-7116-422e-b40c-b40846461213.png" width="300">

デフォルトだとこんな感じです。

動きはタップすると、カレンダーがポップアップします。
動き的にはUIKitと同じなので割愛します。

- CompactDatePickerStyle　

こちらはdatePickerStyleだけ指定してもDefaultDatePickerStyleの挙動となんら変わりありません。

- WheelDatePickerStyle

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/f06bc50a-52b5-3fce-2958-5a79bfa13db0.png" width="300">

こちらは従来通りのweelになります。

- GraphicalDatePickerStyle

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/9a73647e-aa6c-451d-ae8d-4dcaa9c863d6.png" width="300">

こちらはデフォルトだとUIKitでもあった、圧縮されてしまう現象が起きています。
 .frame
でいい感じに調整が必要です。

## Mode

次にMode指定をしてみます。

```swift
 DatePicker("タイトル", selection: $selectionDate, displayedComponents: .hourAndMinute)

```
displayedComponents

- .date
- .hourAndMinute

上記を指定できます。

```swift
DatePicker("タイトル", selection: $selectionDate, displayedComponents: .date)
     .datePickerStyle(DefaultDatePickerStyle())
     .labelsHidden()

```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/8729630b-cdb0-449e-1594-e32825a58558.png" width="300">


```swift
DatePicker("タイトル", selection: $selectionDate, displayedComponents: .hourAndMinute)
     .datePickerStyle(DefaultDatePickerStyle())
     .labelsHidden()

```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/3d7e9d89-0ef3-fb19-b628-081d20af5691.png" width="300">


上記の挙動としては

- DefaultDatePickerStyle
- CompactDatePickerStyle

共に同じ表示でした。


```swift
 DatePicker("タイトル", selection: $selectionDate, displayedComponents: .date)
      .datePickerStyle(WheelDatePickerStyle())
      .labelsHidden()
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/c37eadb2-d5c3-30a1-25eb-459ad5c87e1b.png" width="300">


```swift
DatePicker("タイトル", selection: $selectionDate, displayedComponents: .hourAndMinute)
     .datePickerStyle(WheelDatePickerStyle())
     .labelsHidden()
            
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/3dc25408-0b0b-e581-1d86-321fe1d18bcd.png" width="300">

こちらに関してはやはり通常で、日にち表示なのか、時間表示なのかの違いでした。


```swift
DatePicker("タイトル", selection: $selectionDate, displayedComponents: .date)
     .datePickerStyle(GraphicalDatePickerStyle())
     .labelsHidden()
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/d4242933-1c7d-a95e-65c1-5f93991fd6b4.png" width="300">

こちらに関してはTimeを消したとしてもやはり圧縮されてしまいます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/875a36c4-32ed-0e24-bc36-b325a11b4dec.png" width="300">

```swift
.frame(width: 300, height: 500)
```
フレーム指定してあげると、表示が正常になります。
が、サイズによってバグります（widthを４００にしたらバグった）
これは使うのは厳しそうですね。。

```swift
DatePicker("タイトル", selection: $selectionDate, displayedComponents: .hourAndMinute)
     .datePickerStyle(GraphicalDatePickerStyle())
     .labelsHidden()
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403613/58c36d15-91a8-73e3-6a66-938aa0dec429.png" width="300">

時間のみだと、カレンダーのTimeの部分だけ表示されるようになりました。


## まとめ
今回はSwiftUIでの挙動を調べてみました。
使用する場合によってかもしれませんが、
GraphicalDatePickerStyleに関しては、UIKit同様バグというか表示に癖があるので、現段階ではどうしてもということがない限りあまり使わない方実装を考えた方が良さそうです。
正直あまり使わないかな〜とも思ったりもしてます。


まあ、宣言的にCodeをかけるのはやはりSwiftUIの強みだし、SwiftUIは書いてて楽しいので、
今後よくなることを期待して今回の調査を終えたいと思います。

次回はiOS14の位置情報の変更に関しての挙動でも書こうかと思います。

読んでいただきありがとうございました。


UIKit版はこちら
[iOS14でのUIDatePickerの挙動について(UIKit)](https://qiita.com/kj_trsm/items/a53b0b3f7e1bc7c06106)