Listビューに表示したアイテムを削除する方法
- アイテムを右スワイプしてDeleteボタンを押す
- 3D Touchで削除ボタン入りのコンテキストメニューを出し、削除ボタンを押す
の2通りが考えられます。
今回は1つ目の方法を試してみます。
テスト用のリストを作る
このようなListビューを作りました。
果物の名前がオレンジ色でリスト表示されます。
アイテムをタップすると、画面遷移し選んだ果物の名前を表示するだけです。
とてもシンプルなものです。
@State var fruits = ["りんご", "みかん", "バナナ", "メロン", "ぶどう", "かき", "いちご"]
var body: some View {
List {
ForEach(fruits, id: \.self) { fruit in
NavigationLink(destination: NextView(selectedFruit:fruit)) {
Text(fruit)
.foregroundColor(.orange)
}
}
}
}
struct NextView:View
{
var selectedFruit:String = "無し"
var body: some View {
VStack {
Text("選んだ果物:" + selectedFruit)
}
}
}
Deleteボタンを表示する
先ほどのListビューにモディファイアを追加します。
@State var fruits = ["りんご", "みかん", "バナナ", "メロン", "ぶどう", "かき", "いちご"]
var body: some View {
List {
ForEach(fruits, id: \.self) { fruit in
NavigationLink(destination: NextView(selectedFruit:fruit)) {
Text(fruit)
.foregroundColor(.orange)
}
}
.onDelete { offsetIndex in
NSLog("Tap Delete Button!!")
}
}
}
ここで注意しておきたいのが、Listビューではなく、ForEachにモディファイアを設定している点です。
削除ボタンで削除するのはListビューではなく、その中の各アイテムですからね。
これでアイテムを右にスワイプするとDeleteボタンが表示されます。
Deleteボタンをタップすると、ログにTap Delete Button!!
と表示されます。
Deleteボタンタップ時の処理を追加する
追加したモディファイアを詳しく見てみましょう。
.onDelete { offsetIndex in
NSLog("Tap Delete Button!!")
}
NSLog("Tap Delete Button!!")
は見ての通りDeleteボタンをタップしたときの処理です。
offsetIndex
は、Deleteボタンをタップしたアイテムのインデックスが入っています。
ですので、この値を使って配列のアイテムを操作すれば良いことになります。
ちなみに、offsetIndex
は対象となるコレクション一式を表す構造体であるIndexSet
型です。
表示しているアイテムを削除する
渡されたインデックスを用いて配列のアイテムを削除すればOKです。
このとき、配列に状態を監視する@State
を付けておいたので、中身が変わった時点でListビューが更新されます。
.onDelete { offsetIndex in
self.delete(offset: offsetIndex)
}
(中略)
func delete(offset:IndexSet)
{
fruits.remove(atOffsets: offset)
}
ちょっと心配になるほどお手軽。
DBのデータを削除する
ここでは具体的にコードを示さず、方針だけにします。
CoreDataを勉強しているところなので……
- 削除対象のアイテムに関するID(orアイテムを特定できる何か)を取得する
- DBからデータを削除する
- 再度DBから値を取得する
- Listビューの更新をする(
@State
頼み)
おおよそこの流れのメソッドを作って、onDelete
モディファイアにて呼び出せば、おそらく大丈夫でしょう。
あらためて作ってみます。
気になること
- Deleteの文言と文字色を変えることはできるのか
- ボタンの背景色を変えることができるのか
- UITableViewControllerで可能だった複数ボタンを配置したい
- 左から右のスワイプは可能なのか
要はUITableViewControllerでできたことがSwiftUIでどこまで再現可能なのかという点。