SwiftUI のリストで選択した要素を使った例を説明します。
Sponsor Link
環境&対象
以下の環境で動作確認を行なっています。
- macOS Monterery beta 5
- Xcode 13 beta5
- iOS 15 beta
SwiftUI の List
SwiftUI の List は、要素をリスト表示する機能に加えて、要素を選択する機能も持っています。
List で要素をリスト表示
struct ContentView: View {
@State private var listElements = ["First", "Second", "Third", "Forth"]
var body: some View {
VStack {
GroupBox("List") {
List(listElements, id: \.self) { element in
Text(element)
}
}
.padding()
}
}
List で要素を選択
List は、リスト表示に加えて要素を選択する機能も持っています。
選択表示は、iOS, macOS でそれぞれのプラットフォームに応じた表示になります。
単数選択か複数選択かは、List に与える引数で制御することができます。
具体的には、selection 引数に Optional 型の変数を指定すると 単数選択を指定することになり、Set 型の変数を指定すると複数選択できるよう指定することになります。
以下のコードは複数選択できるように、Set を引数に与えています。
struct ContentView: View {
@Environment(\.editMode) var editMode
@State private var listElements = ["First", "Second", "Third", "Forth"]
@State private var selection: Set<String> = Set()
var body: some View {
VStack {
GroupBox("List") {
List(listElements, id: \.self, selection: $selection) { element in
Text(element)
}
}
}
.onAppear {
editMode?.wrappedValue = .active
}
.padding()
}
}
選択結果を参照する
単数選択
selection には、Optional 型を渡すと 単数選択になります。
何も選択していない状態では、nil がセットされ、選択されていればその要素がセットされています。
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2021/08/26
// © 2021 SmallDeskSoftware
//
import SwiftUI
import SwiftUIDebugUtil
struct ContentView: View {
@Environment(\.editMode) var editMode
@State private var listElements = ["First", "Second", "Third", "Forth"]
@State private var selectedOne: String? = nil
var body: some View {
VStack {
GroupBox("List") {
List(listElements, id:\.self, selection: $selectedOne) { element in
Text(element)
}
}
.onAppear {
editMode?.wrappedValue = .active
}
GroupBox("Selection") {
Text("Selection: \(selectedOne == nil ? "None" : selectedOne!)")
}
.frame(minHeight: 300)
}
.padding()
}
}
複数選択
複数アイテムの場合は、Set 型に 選択された要素の情報が保存されています。
//
// ContentView.swift
//
// Created by : Tomoaki Yagishita on 2021/08/26
// © 2021 SmallDeskSoftware
//
import SwiftUI
import SwiftUIDebugUtil
struct ContentView: View {
@Environment(\.editMode) var editMode
@State private var listElements = ["First", "Second", "Third", "Forth"]
@State private var selection: Set<String> = Set()
var body: some View {
VStack {
GroupBox("List") {
//EditButton()
List(listElements, id: \.self, selection: $selection) { element in
Text(element)
}
}
.onAppear {
editMode?.wrappedValue = .active
}
GroupBox("Selection") {
ForEach(Array(selection), id: \.self) { selected in
Text(selected)
}
}
.frame(minHeight: 300)
}
.padding()
}
}
まとめ:List での選択要素
List での選択要素
- 単数選択であれば、Optional 形で selection: に渡す
- 複数選択であれば、Set 形で selection: に渡す
- iOS/iPadOS では、editMode を制御しないと選択可能にならない
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
Sponsor Link
参考にさせていただいております。
TodoListを応用してチェックリスト及び結果ページを作成しプリンターでプリントアウトできるアプリを作成しております。
こちらの内容で複数選択をTextとして表示でき、また別ページの結果Viewへ反映することまでできました。
CoreDataを用いてデータ保存もやりたいと思っております。
そこで質問なのですが、こちらのページで紹介されているようにSet型にしたものをCoreDataで保存する際、Cannot assign value of type ‘Set’ to type ‘String’このようなエラーがでてどうしたらいいか悩んでおります。
よろしければ教えていただければ幸いです。
コメント欄へこのような質問を行なっていいのかわからなかったのですが藁をも掴む思いでさせていただきました。
不都合があるようでしたら大変申し訳ありません。
こんにちは。
書いていただいている情報だけではいろいろと原因が考えられるので、解決策を提示することは難しいです。
(意味的には、String 型の変数(?) に Set 型の情報を設定しようとしているのでエラー と言う内容ですが・・・)
途中までで書きかけになっていますが、この記事が参考になるかもしれません
他には 直接の回答ではありませんが、SwiftUI と CoreData を使って、MVVM というアーキテクチャパターンで TODO アプリを作る記事を書いているので、参考になる箇所があるかもしれません。
MVVM に焦点をあてているので、CoreData の説明はあまりなく、全15回と 少し長いですが、記事へのリンクはこちらです。