【初心者】Swift UIを勉強する その⑨ ーーー Identifiableプロトコル

# はじめに

前回はカードのアニメーションを綺麗にできました。
しかし、カード１枚のみの場合はそれでいいですけど、100枚の場合は一個一個作るわけにはいかないです。
今回はこれについてやっていきます。　完成品↓

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/c4c3d4e5-fd05-f466-7bc6-02b59413cf1b.gif" width=40%>　　



# 目次
<!-- タイトルとアンカー名を編集 -->
1. [Identifiableプロトコル](#Identifiableプロトコル)
2. [まとめ](#まとめ)
3. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Identifiableプロトコル"></a>
# Identifiableプロトコル
・まずはデータモジュールファイル`Course`を作成します。
・Identifiable使うことによって、titleやsubtitleなど、他のデータフィールドが変更されても、idプロパティを使用すれば特定のデータを識別できます。
・全部は載せないですが、データは`course[]`コレクションに足していきます。
また、idは自動生成のため、コレクションに準備する必要はありません。

```swift:Course.swift
struct Course: Identifiable {
    var id = UUID()
    var title: String
    var subtitle: String
    var color: Color
    var image: String
    var logo: String
    var show: Bool
    var index: Double
}

var courses = [
    Course(
        title: "UI Design for iOS 14",
        subtitle: "20 sections",
        color: Color(.blue),
        image: "Illustration 1",
        logo: "Logo UI Design",
        show: false,
        index: -1
     )
]
```
<br>
・`CoursesView`に戻して、前回の記事では2枚目のカードを作成したけど、100枚を作りたい時はあたりまえですが、ループを使います。
・itemはなぜidを持つかについて、[クロージャ](https://www.isoroot.jp/blog/3000/)を調べてみましょう。
itemにカーソルを合わせて、`CTRL+CMD+j`を押せば、`Course`に飛んで行きます。



<br><br>
・`ForEach`で100枚のカードを作ったとしてたら、一枚一枚の中身を決めないといけません。
・matchedGeometryEffectの識別子は`courses[].id`に変えます。ここの引数20は何枚目のカードをタップしても0枚目のカードが開きます。

```swift:CoursesView.swift
if show {
    ScrollView {
         CourseItem()
              .matchedGeometryEffect(
                  id: courses[0].id, in: namespace
               )
              .frame(height: 300)
          VStack {
              ForEach(0 ..< 20) { item in
                  CourseRow()
              }
          }
          .padding()
    }
}
```

<br>
・`Course.swift`を作成したことによって、`CourseItem.swift`で定数で決めた`Image`と`Text`をデータモジュールに変えます。

```swift:CoursesItem.swift
var course: Course = courses[0]
    
    var body: some View {
        VStack(alignment: .leading, spacing: 4.0) {
            Spacer()
            HStack {
                Spacer()
                Image(course.image)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                Spacer()
            }
            Spacer()
            Text(course.title)
                .fontWeight(.bold)
                .foregroundColor(Color.white)
            Text(course.subtitle)
                .font(.footnote)
                .foregroundColor(Color.white)
        }
```

<br>
・まだ`CoursesView.swift`に戻って、`CourseItem()`に引数を追加します。

```swift:CoursesView.swift
ScrollView {
      VStack(spacing: 20) {
           ForEach(courses) { item in
                CourseItem(course: item)
                     .matchedGeometryEffect(
                         id: item.id, in: namespace, isSource: !show
                     )
                     .frame(width: 335, height: 250)
            }
       }
       .frame(maxWidth: .infinity)
}
if show {
   ScrollView {
        CourseItem(course: courses[0])
           .matchedGeometryEffect(id: courses[2].id, in: namespace)
           .frame(height: 300)
        VStack {
             ForEach(0 ..< 20) { item in
                  CourseRow()
          }
    }
    .padding()
}
```



<a id="#まとめ"></a>
# まとめ
・今回はIdentifiableプロトコルを使って、`Course`Structを一意に識別できるようにした。
ただし、選択された`CourseItem`はまだ`courses[0]`のように、固定のままです。次回のこれを解決します。

**ソースコード[Github](https://github.com/wsimple1028/swiftUI_ios14)**

<a id="#reference"></a>
# 参考文献
- [Design Code --- SwiftUI for iOS 14](https://designcode.io/swiftui-ios14)