【SwiftUI】[選択リスト編]Listの使い方

概要

前回に引き続き今回はSwiftUIの選択リスト表示について紹介したいと思います。

環境

Xcode 13.3.1
Swift 5.6

選択リスト

チェックリストなどの選択可能なリストを作成するにはListのselectionを使用します。
selectionには一意になる選択値を格納する必要があります。
ForEachでループして取得する型と選択値を格納するselectionの型を合わせる必要があります。

単一選択(index指定)

単一選択のリストを作成してみます。
下記の例ではForEachでInt型のindexをループしているのでselectionもIntにします。

struct ContentView: View {
    @State private var selectionValue: Int? = nil
    let fruits = ["りんご", "みかん", "いちご"]
    var body: some View {
        VStack {
            if let selectionValue = selectionValue {
                Text("\(selectionValue)番目を選択")
            } else {
                Text("未選択")
            }
            List(selection: $selectionValue) {
                ForEach(fruits.indices, id: \.self) { index in
                    Text(fruits[index])
                }
            }
            .environment(\.editMode, .constant(.active))
        }
    }
}

単一選択(tag指定)

上記のようにForEachの場合は、ループしているindexがselectionに格納されましたが、ForEachを使用しない場合はtag()を使うとよさそうです。
ForEachを使用した場合であってもtagを設定するとtagが優先されるようです。

struct ContentView: View {
    @State private var selectionValue: Int? = nil
    var body: some View {
        VStack {
            if let selectionValue = selectionValue {
                Text("\(selectionValue)を選択")
            } else {
                Text("未選択")
            }
            List(selection: $selectionValue) {
                Text("りんご").tag(10)
                Text("みかん").tag(20)
                Text("いちご").tag(30)
            }
            .environment(\.editMode, .constant(.active))
        }
    }
}

tagには文字列も設定できます。
tagがString型なので選択値を格納するselectionもString型にする必要があります。

struct ContentView: View {
    @State private var selectionValue: String? = nil
    var body: some View {
        VStack {
            if let selectionValue = selectionValue {
                Text("\(selectionValue)を選択")
            } else {
                Text("未選択")
            }
            List(selection: $selectionValue) {
                Text("りんご").tag("あ")
                Text("みかん").tag("い")
                Text("いちご").tag("う")
            }
            .environment(\.editMode, .constant(.active))
        }
    }
}

複数選択(index指定)

複数選択のリストを作成してみます。
selectionの型をSetにすると複数選択が可能になります。

struct ContentView: View {
    @State private var selectionValue: Set = []
    let fruits = ["りんご", "みかん", "いちご", "れもん"]
    var body: some View {
        VStack {
            if !selectionValue.isEmpty {
                Text("\(selectionValue.description)番目を選択")
            } else {
                Text("未選択")
            }
            List(selection: $selectionValue) {
                ForEach(fruits.indices, id: \.self) { index in
                    Text(fruits[index])
                }
            }
            .environment(\.editMode, .constant(.active))
        }
    }
}

選択値の重複

selectionに格納する選択値は必ずユニーク(一意)にしましょう。
下記の例ではselectionに格納する選択値の”りんご”が重複しているためおかしな動きになっています。
(0番目のりんごを選択したのに3番目のりんごも選択されています)

struct ContentView: View {
    @State private var selectionValue: String? = nil
    let fruits = ["りんご", "みかん", "いちご", "りんご"]
    var body: some View {
        VStack {
            if let selectionValue = selectionValue {
                Text("\(selectionValue)を選択")
            } else {
                Text("未選択")
            }
            List(selection: $selectionValue) {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
            }
            .environment(\.editMode, .constant(.active))
        }
    }
}

スポンサーリンク
PR
PR

シェアする

  • このエントリーをはてなブックマークに追加

フォローする