選択モード(selection)
List では行の選択機能を実装できます。単一選択と複数選択の両方に対応しており、ファイル管理アプリやメールアプリのような UI を構築できます。
単一選択
単一の行を選択する場合は、選択中の ID を保持する @State 変数を用意し、selection パラメータにバインディングを渡します。
struct ContentView: View {
let fruits = ["りんご", "みかん", "バナナ", "ぶどう"]
@State private var selectedFruit: String?
var body: some View {
List(fruits, id: \.self, selection: $selectedFruit) { fruit in
Text(fruit)
}
}
}選択された行は自動的にハイライトされます。選択を解除するには、同じ行をもう一度タップするか、selectedFruit = nil を設定します。
複数選択
複数の行を選択する場合は、Set を使います。
struct ContentView: View {
let items = ["項目A", "項目B", "項目C", "項目D", "項目E"]
@State private var selectedItems: Set<String> = []
var body: some View {
NavigationStack {
List(items, id: \.self, selection: $selectedItems) { item in
Text(item)
}
.navigationTitle("選択: \(selectedItems.count)件")
.toolbar {
EditButton()
}
}
}
}複数選択を有効にするには、通常 EditButton で編集モードに入る必要があります。
選択状態に応じた処理
選択されたアイテムに対して一括操作を行う例です。
struct FileListView: View {
@State private var files = ["書類A.pdf", "書類B.pdf", "画像.png", "動画.mp4"]
@State private var selectedFiles: Set<String> = []
var body: some View {
NavigationStack {
VStack {
List(files, id: \.self, selection: $selectedFiles) { file in
Label(file, systemImage: iconForFile(file))
}
if !selectedFiles.isEmpty {
HStack {
Button("削除") {
files.removeAll { selectedFiles.contains($0) }
selectedFiles.removeAll()
}
.foregroundColor(.red)
Spacer()
Button("共有") {
// 共有処理
}
}
.padding()
}
}
.toolbar {
EditButton()
}
}
}
func iconForFile(_ name: String) -> String {
if name.hasSuffix(".pdf") { return "doc.fill" }
if name.hasSuffix(".png") { return "photo" }
if name.hasSuffix(".mp4") { return "video" }
return "doc"
}
}単一選択
Optional 型(例: String?)を使用。nil で選択なしを表す。
複数選択
Set 型(例: Set<String>)を使用。空の Set で選択なしを表す。
Identifiable な型での選択
カスタム型を使う場合は、id の型を selection の型に合わせます。
struct Item: Identifiable {
let id = UUID()
var name: String
}
struct ContentView: View {
let items = [Item(name: "A"), Item(name: "B"), Item(name: "C")]
@State private var selectedID: UUID?
var body: some View {
List(items, selection: $selectedID) { item in
Text(item.name)
}
}
}編集モードなしでの選択
iOS 16 以降では、編集モードでなくても複数選択を可能にする方法があります。
struct ContentView: View {
let items = ["A", "B", "C", "D"]
@State private var selected: Set<String> = []
var body: some View {
List(items, id: \.self) { item in
HStack {
Image(systemName: selected.contains(item) ? "checkmark.circle.fill" : "circle")
.foregroundColor(selected.contains(item) ? .blue : .gray)
Text(item)
}
.contentShape(Rectangle())
.onTapGesture {
if selected.contains(item) {
selected.remove(item)
} else {
selected.insert(item)
}
}
}
}
}この方法では標準の selection 機能を使わず、タップジェスチャーと状態管理で独自に実装しています。より細かいカスタマイズが可能です。











