概要
前回に引き続き今回は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))
}
}
}