【SwiftUI】リスト表示(一覧画面)から詳細画面への遷移
本記事では、メモアプリなどにあるようなリスト表示の画面から、各リストをクリックして詳細画面へ遷移する方法を解説していきます。
リストの作成、詳細画面作成、リストから詳細画面への遷移の順番で解説していきます。
リスト表示
今回使用するリストは、画像とその画像のタイトルを表示したInstagramやTwitterのフォロー一覧のようなイメージです。リスト一覧の表示方法も3つの手順で進めていきます。
「file」→「new」→「file…」からSwiftFileを選択し、任意のファイル名で新規作成します。今回はImageDataListというファイル名でファイルを作成しました。
リストに表示する画像と画像タイトルのデータ一覧を定義
まずは、画像/タイトル/画像の説明文のデータを1つのかたまりとして扱うための構造体を定義し、その構造体に入れるためのデータを作成します。
構造体の定義はstructを用いて行い、Identifiableプロトコルに準拠した形で定義するため、構造体に必要な画像/タイトル/画像の説明文の他に、idプロパティを指定します。構造体名は任意で、今回はImageDataという名前で定義します。
プロトコルはクラスや構造体などを定義する際の規約や規格を定義しているルールのことを表しています。そしてIdentifiableプロトコルはidプロパティが必須になるというルールを付与するプロトコルです。
今回定義した構造体はList内に入れて、そこからループ処理などでデータを取り出して画面表示を行います。List内からデータを取り出して扱う場合にはList内のそれぞれのデータが一意に識別できる必要があります。よって、各構造体を一意に識別するためにIdentifiableプロトコルに準拠した構造体を定義して、idプロパティを含める必要があります。
struct ImageData: Identifiable{
var id = UUID()
var imageName:String
var imageTitle:String
var imageText:String
}
構造体を定義したら、imageListというリスト型の変数を作成して、その中に構造体型のデータを入れていきます。
idプロパティはvar id = UUID()で定義しているため、自動で採番されるので値を入れる必要はありません。
構造体の定義とListへの格納は以下の形で完成です。

リスト1行分のViewを定義
「file」→「new」→「file…」からSwiftUI Viewを選択し、任意のファイル名で新規作成します。今回はRowというファイル名でファイルを作成しました。
画面に表示するリストの1行分のビューを作成します。1行のリストは画像+タイトルで以下のように表示します。

Hstackを利用して画像とタイトルを横並びに表示し、画像は丸めて周りを青い枠で囲みます。
プレレビューにはImageDataListのリスト内のデータを代入した任意の一行を入れてプレビューを表示確認できます。
import SwiftUI
struct Row: View {
var imageData: ImageData
var body: some View {
HStack{
Image(imageData.imageName)
.resizable()
.frame(width: 50, height: 50)
.clipShape(Circle())
//青い外枠を重ね合わせる
.overlay(Circle().stroke(Color.blue))
Text(imageData.imageTitle)
Spacer()
}
}
}
#Preview {
Row(imageData: imageList[0])
.previewLayout(.sizeThatFits)
}
表示結果

ImageDataListファイル内で宣言した構造体であるImageData型のimageDataという変数を宣言し、そこからプロパティを取り出す形で画像と画像タイトルを表示しています。
用意したリストを表示
ここまでで作成した、構造体とそのリスト、そして構造体を利用した一行分のビューを利用してcontentView.swift内でリスト表示を行います。ContentView内のコードは以下の通りです。
struct ContentView: View {
var body: some View {
VStack {
List(imageList){ item in
Row(imageData: item)
}
}
.padding()
}
}
List内にはImageDetailListファイル内で宣言したimageListをループ処理します。
ループ内では、一行分のビューを定義したRowにimageList内の各要素を渡して表示していきます。
表示結果

詳細画面表示
一覧画面からの遷移先となる詳細画面を作成していきます。詳細画面は、画像とタイトル、説明文テキストの3つの要素で構成します。
「file」→「new」→「file…」からSwiftUI Viewを選択し、DetailViewという名前でファイルを作成します。
struct DetailView: View {
var imageData: ImageData
var body: some View {
VStack{
Image(imageData.imageName)
.resizable()
.aspectRatio(contentMode: .fit)
Text(imageData.imageTitle).font(.title)
.padding()
Text(imageData.imageText)
Spacer()
}
.padding()
}
}
var imageData: ImageDataで、構造体型の変数を定義し画像データ、タイトル、テキストを表示します。
表示結果

プレビュー画面に表示するために、ImageData構造体のリストデータであるimageListの先頭の0番目を渡しています。
#Preview {
DetailView(imageData: imageList[0])
}
詳細画面遷移
ここまでで作成してきた一覧画面と詳細画面を繋ぎ合わせて、一覧画面→詳細画面と詳細画面→一覧画面の動きを実現していきます。
変更するのはContentViewファイルとなり、NavigationViewを利用して、別画面への遷移を実現します。
struct ContentView: View {
var body: some View {
NavigationView{
List(imageList){ item in
NavigationLink(destination: DetailView(imageData: item)){
Row(imageData: item)
}
}
}
}
}
NavigationViewとは、アプリケーション内での画面遷移を関する機能で、view内でNavigationViewに囲まれた要素は画面遷移を行うための要素として利用することができます。
NavigationVIew内で利用しているNavigationLinkは、中にある要素を他画面へ遷移するリンクとすることができます。今回の例では、NavigationLinkで囲まれているリストの一行一行が詳細画面へのリンクとなります。
NavigationLinkの引数にはdestinationを指定し、引数では遷移先を指定することができます。遷移先には、すでに詳細画面として用意しているDetailViewに各列の構造体データを引数として渡しています。そのため、リンクとなった各行をクリックすると対応した詳細画面へ遷移できます。

リスト内の一番上の「海の風景」をクリック↓

画面遷移できることを確認できれば完成です!
最後に
長々とお付き合いいただきありがとうございます。本記事では、リスト表示から詳細画面へ遷移する例を画像つきで解説してきました。画面遷移はNavigationLinkを使用することでとても簡単に実装できることがお分かりいただけたかと思います。
他にもSwiftUIのリスト表示にフォーカスした記事やインスタンスなどについても記事を書いておりますのでぜひそちらもご確認下さい。
-
前の記事
【SwiftUI】リスト(一覧表示)に検索ボックスをつける方法 2024.02.23
-
次の記事
【SwiftUI】テキストエディタの作成とデータ保存 2024.04.01