Listビューのアイテムを削除する

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ボタンが表示されます。

バナナをSwipe

Deleteボタンをタップすると、ログにTap Delete Button!!と表示されます。

丑三つ時のDelete

Deleteボタンタップ時の処理を追加する

追加したモディファイアを詳しく見てみましょう。

.onDelete { offsetIndex in
    NSLog("Tap Delete Button!!")
}

NSLog("Tap Delete Button!!")は見ての通りDeleteボタンをタップしたときの処理です。

offsetIndexは、Deleteボタンをタップしたアイテムのインデックスが入っています。
ですので、この値を使って配列のアイテムを操作すれば良いことになります。

ちなみに、offsetIndexは対象となるコレクション一式を表す構造体であるIndexSet型です。

IndexSet | Apple Developer Documentation
A collection of unique integer values that represent the indexes of elements in another collection.

表示しているアイテムを削除する

渡されたインデックスを用いて配列のアイテムを削除すれば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でどこまで再現可能なのかという点。

タイトルとURLをコピーしました