選択可能なListを生成する方法を解説します。
環境
この記事の情報は次のバージョンで動作確認しています。
【Swift】5.3.1
【iOS】14.2
【macOS】Catalina バージョン 10.15.7
単項目選択
選択可能なListを生成するには、次の2つの条件があります。
- 引数(selection)に選択値を格納するプロパティを指定する。
- 対象のViewを編集モードにする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
struct ContentView: View { @State private var selectionValue: Int? = nil var body: some View { VStack { Text("選択アイテム: \(selectionValue ?? 0)") List(selection: $selectionValue) { Text("みかん").tag(10) Text("ぶどう").tag(20) Text("りんご").tag(30) } .environment(\.editMode, .constant(.active)) } } } |
この例では、引数(selection)に選択値を格納するプロパティとして、selectionValueを指定しています。
各行に付加する.tag()は対象のViewを特定する目印です。この値がselectionに連携します。
tagの型はHashableプロトコルに準拠していれば良いので、数値、文字列等のSwift標準の型がほぼ使えますが、selectionで指定するプロパティと型を合わせる必要があります。
environmentモディファイアで、Listビューの編集モード(editMode)をactiveに設定しています。
環境変数editModeはBinding型なので、Binding型の値を生成するconstantメソッドを使用して値を設定します。
複数項目選択
引数(selection)に渡すプロパティの型をSet型(Hashableな要素の集合)にすると、複数選択が可能になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
struct ContentView: View { @State private var selectionValues: Set<Int> = [] var body: some View { VStack { Text("選択アイテム:\(selectionValues.description)") List(selection: $selectionValues) { Text("みかん").tag(10) Text("ぶどう").tag(20) Text("りんご").tag(30) } .environment(\.editMode, .constant(.active)) } } } |
Listを繰り返し処理(ForEach)で生成した場合
ForEachを使った繰り返し処理でリストを生成した場合は.tag()による値の設定は不要となります。
ForEachには、【範囲指定】と【データ指定】の2種類の繰り返しがあります。
ForEachについて、詳しくはこちらの記事で解説しています。
範囲指定によるリストの生成
範囲指定によるList生成のケースでは、データ列のインデックス(0から始まる)がselectionと連携します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
struct ContentView: View { let fruits = ["みかん", "ぶどう", "りんご", "みかん"] @State private var selectionValue: Int? = nil var body: some View { VStack { Text("選択アイテム: \(selectionValue ?? 99 )") List(selection: $selectionValue) { ForEach(0 ..< fruits.count) { index in Text(fruits[index]) } } .environment(\.editMode, .constant(.active)) } } } |
データ指定によるリストの生成
データ指定によるListの生成時には、idに設定した値がselectionと連携します。
この例ではidを配列の要素(文字列)としていますので、selectionで指定するプロパティ(selectionValue)も文字列で宣言する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
struct ContentView: View { let fruits = ["みかん", "ぶどう", "りんご"] @State private var selectionValue: String? = "" var body: some View { VStack { Text("選択アイテム: \(selectionValue ?? "" )") List(selection: $selectionValue) { ForEach(fruits, id: \.self) { fruit in Text(fruit) } } .environment(\.editMode, .constant(.active)) } } } |
idに指定される値は基本的にユニークであるのが前提となります。
配列に同名の要素があった場合、想定外の動きになりますので注意してください。