【SwiftUI】Listの行削除

(2020/05/9 更新)

Listで生成したデータ一覧の行削除処理について解説します。

スポンサーリンク

環境

この記事の情報は次のバージョンで動作確認しています。

【Xcode】11.4.1
【Swift】5.2
【iOS】13.4.1
【macOS】Catalina バージョン 10.15.4

前提条件

行削除ができるのは、次の条件を満たしたリストです。

  1. リストに関連付けられたコレクション(配列)が、@State等で宣言されており、更新可能である。
  2. List + ForEach でリストが生成されている。
    →行削除処理はForEachのModifierを使って実現します。
  3. ForEachは範囲指定ではなくid指定による繰り返し。
    →各行の一意性が確保されている必要があります。

前提条件

行削除処理の追加

ForEachの ModifierであるonDelete()で行削除時に呼び出すメソッドを指定します。
呼び出し方は"(削除対象:IndexSet) -> Void"の形式になります。

呼び出されるメソッド(rowRemove)には、コレクション(配列)から要素を削除す処理を記述します。
この中で使用しているremove(atOffsets:)は、RangeReplaceableCollectionプロトコルで宣言されている,
iOS13以降でのみ使用可能なメソッドです。

行削除処理の追加

対象行をスワイプするだけで、行削除が可能になります。

編集モードの切り替えボタン追加

リストを編集モードに切り替えると、スワイプとは異なる操作で行削除が行えます。
以下は編集モードの切り替えをするEditButtonをナビゲーションボタンとして配置した例です。

Editボタンを押して編集モードにすると、次のようにタップで削除行を選べるようになります。

編集モードの切り替えボタン追加

スワイプによる削除を止める

スワイプによる操作はユーザーが意図せず行を削除してしまう可能性が少なからずあります。
スワイプによる削除を止めて、編集モードでのみ削除できるようにする方法を紹介します。

以下は環境変数のeditModeを参照し、編集モードの場合のみ削除機能を有効にする例です。

同一のViewでNavigationViewを使用していると、編集モードが取得できないSwiftUIの不具合がある為、Viewを分割しています。
不具合情報に関して、詳しくはこちらを御覧ください。

【SwiftUI】編集モードの取得に関する不具合
編集モード(editMode)の取得に関する不具合と思われる現象に遭遇したので、対処方法と一緒に記録を残しておきます。

あわせて読みたい記事

【SwiftUI】Listの使い方
Listはデータの一覧表示をするのに適したViewです。画面に収まらない量の場合はスクロール表示になるなど、UIKitのUITableViewに似ていますが、はるかに簡単に使えます。ListはForEachとセットで使うケースが多いの...
【SwiftUI】Listの行入れ替え
Listの行入れ替え処理の実現方法について解説します。
【SwiftUI】Viewの分割
(2020/03/10 更新)複雑なViewを小さなViewに分割する事で、繰り返しを避け、ソースを見やすくする方法を紹介します。Viewを分割してもパフォーマンスに大きな影響を及ぼさないのがSwiftUIの特徴の一つです。