結構調べたけど、日本語の資料がなかったので備忘録として残しておく。
やりたかったこと
以下のようにCoreDataを参照したリストを横スワイプで削除したかった。
UIの要素だけでなく、元データごと削除する。
よく他のページで見かける以下のような実装だとCoreDataの型が合わず処理がうまくいかない。
struct ContentView: View {
@State private var data = ["one", "two", "three"]
var body: some View {
List {
ForEach(data, id: \.self) { data in
Text(data)
}
/// 行削除操作時に呼び出す処理の指定
.onDelete(perform: rowRemove)
}
}
/// 行削除処理
func rowRemove(offsets: IndexSet) {
data.remove(atOffsets: offsets)
}
}
やったこと
1.CoreDataが使えるようになっているか以下の設定を確認する。
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(
entity: TestCoreData.entity(),
sortDescriptors: [
NSSortDescriptor(keyPath: \TestCoreData.name, ascending: true),
]
) var testCoreData: FetchedResults<TestCoreData>
2.以下のようなリストに対して.onDelete(perform:〜)を追加。
List {
ForEach(testCoreData, id: \.self) { testCoreData in
Text("Creator: \(testCoreData.creator ?? "Anonymous")")
}.onDelete(perform: removeCoreData)
}
3.リストの番号を保持したoffsetsを使って、削除するCoreDataの要素を指定。
func removeCoreData(at offsets: IndexSet) {
for index in offsets {
let putTestCoreData = testCoreData[index]
managedObjectContext.delete(putTestCoreData)
}
}
以上!!