5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【SwiftUI】Listを作成する

Last updated at Posted at 2022-01-29

環境

Xcode 13.2.1
Swift 5.5.2

Listとは

SwiftUIでは、これまでのUIKitのUITableViewやUICollectionViewを用いたリスト表示を実装したい場合は、Listを使うことで再現ができます。
Listも表示が画面からはみ出た範囲をスクロールできるようになっています。
一番シンプルにListを用いた静的リストの実装は以下になります。Listも表示が画面からはみ出た範囲をスクロールできるようになっています。

var body: some View {
    List {
        Text("First Item")
        Text("Second Item")
        Text("Third Item")
    }
}

動的リストを作成する

動的にリストを作成した場合は以下のように実装することができます。Identifiableに準拠したFruitの配列からListを作成しています。
FruitListItemViewは、Listの1つのデータを表示するためのViewです。

struct Fruit: Identifiable {
    let id = UUID()
    let name: String
}

struct FruitListItemView: View {
    var fruit: Fruit
    
    var body: some View {
        Text(fruit.name)
    }
}

struct ContentView: View {
    private var fruits = [
        Fruit(name: "Apple"),
        Fruit(name: "Orange"),
        Fruit(name: "Banana"),
        Fruit(name: "peach"),
        Fruit(name: "strawberry")
    ]

    var body: some View {
        List(fruits) {
            FruitListItemView(fruit: fruit)
        }
    }
}

ForEachを用いても同じようにリストを作成することができます。

List {
    ForEach(fruits) { fruit in
        FruitListItemView(fruit: fruit)
    }
}

動的と静的両方をListに含ませることもできます。このように自由なリストを作成することができるのでForEachの方が使う場面は多いと思います。

List {
    Text("Dog")
    Text("Cat")
    ForEach(fruits) { fruit in
        FruitListItemView(fruit: fruit)
    }
}

Identifiableに準拠していないデータを用いる場合はidを指定する必要があります。

private var fruits = [
    "Apple",
    "Orange",
    "Banana",
    "peach",
    "strawberry",
]

var body: some View {
    List {
        ForEach(fruits, id: \.self) { fruit in
            FruitListItemView(fruit: fruit)
        }
    }
}

画面遷移をさせる

リスト表示したデータから画面遷移を実装したい場合はNavigationLinkを使用します。

NavigationView {
    List {
        ForEach(fruits) { fruit in
            NavigationLink(destination: SecondView()) {
                FruitListItemView(fruit: fruit)
            }
        }
    }
}

NavigationViewの中にListを置いていないと、タップができず画面遷移がされないので注意が必要です。

選択可能なリストにする

単一選択や複数選択ができるようにするにはselectionを設定します。

単一選択

選択した値を格納するためのidと同じ型のState変数をListの引数selectionに指定します。

@State private var selectedFruit: UUID?

var body: some View {
    NavigationView {
        List(selection: $selectedFruit) {
            ForEach(fruits) { fruit in
                FruitListItemView(fruit: fruit)
            }
        }
        .navigationTitle("Fruits")
        .toolbar { EditButton() }
    }
}

複数選択

Listの引数selectionに指定する変数をSetにすることで複数選択ができるようになります。

@State private var selectedFruit = Set<UUID>()

セクションを追加する

表示するViewをSectionで囲むことでセクションを追加できます。headerfooterはViewを返すのでTextである必要はありません。ヘッダーのテキストは大文字になるようです。

List {
    Section {
        ForEach(fruits) { fruit in
            FruitListItemView(fruit: fruit, selectedFruit: selectedFruit)
        }
    } header: {
        Text("Fruits")
    } footer: {
        Text("End")
    }
    
    Section {
        ForEach(animals, id: \.self) { animal in
            Text(animal)
        }
    } header: {
        Text("Animals")
    }
}

Listの表示スタイルを変更する

listStyle(_:)モディファイアを指定することでListの見た目を変更することができます。

List {
}
.listStyle(DefaultListStyle())

指定なし or DefaultListStyle

.listStyle(DefaultListStyle())

InsetListStyle

.listStyle(InsetListStyle())

PlainListStyle

.listStyle(PlainListStyle())

GroupedListStyle

.listStyle(GroupedListStyle())

SidebarListStyle

.listStyle(SidebarListStyle())
5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?