はじめに
前回はカードのアニメーションを綺麗にできました。
しかし、カード1枚のみの場合はそれでいいですけど、100枚の場合は一個一個作るわけにはいかないです。
今回はこれについてやっていきます。 完成品↓
目次
Identifiableプロトコル
・まずはデータモジュールファイルCourse
を作成します。
・Identifiable使うことによって、titleやsubtitleなど、他のデータフィールドが変更されても、idプロパティを使用すれば特定のデータを識別できます。
・全部は載せないですが、データはcourse[]
コレクションに足していきます。
また、idは自動生成のため、コレクションに準備する必要はありません。
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
)
]
・`CoursesView`に戻して、前回の記事では2枚目のカードを作成したけど、100枚を作りたい時はあたりまえですが、ループを使います。 ・itemはなぜidを持つかについて、[クロージャ](https://www.isoroot.jp/blog/3000/)を調べてみましょう。 itemにカーソルを合わせて、`CTRL+CMD+j`を押せば、`Course`に飛んで行きます。
・ForEach
で100枚のカードを作ったとしてたら、一枚一枚の中身を決めないといけません。
・matchedGeometryEffectの識別子はcourses[].id
に変えます。ここの引数20は何枚目のカードをタップしても0枚目のカードが開きます。
CoursesView.swift
if show {
ScrollView {
CourseItem()
.matchedGeometryEffect(
id: courses[0].id, in: namespace
)
.frame(height: 300)
VStack {
ForEach(0 ..< 20) { item in
CourseRow()
}
}
.padding()
}
}
・`Course.swift`を作成したことによって、`CourseItem.swift`で定数で決めた`Image`と`Text`をデータモジュールに変えます。
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)
}
・まだ`CoursesView.swift`に戻って、`CourseItem()`に引数を追加します。
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()
}
まとめ
・今回はIdentifiableプロトコルを使って、Course
Structを一意に識別できるようにした。
ただし、選択されたCourseItem
はまだcourses[0]
のように、固定のままです。次回のこれを解決します。
ソースコードGithub