これまでは、リストの並べ替えの実装は、難しくないけれども面倒でした。
けれども、SwiftUI を使うと、非常に簡単に実装することができるので説明します。
けれども、SwiftUI を使うと、非常に簡単に実装することができるので説明します。
Sponsor Link
List と ForEach と .onMove
使用する要素は、以下のものです。
使用する要素
- List
- ForEach
- .onMove
普通のリスト表示には、List を使うかと思いますが、List での表示を、ForEach に分解します、その要素に対して、.onMove modifier を使って、どのように移動するかを実装します。
.onMove の実装
onMove に対しては、引数として、source :IndexSet と destination :Int が渡されてきます。
”どこから” ”どこへ” 移動させるかの情報です。
実は、Array の move メソッドは、同じ引数をとりますので、配列ないの順番入れ替えであれば、onMove で渡された引数をそのまま move に渡すと期待する動作になります。
onMove と move の実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
struct ContentView: View { @State private var dataList = ["item1", "item2", "item3"] var body: some View { List { ForEach( dataList, id: \.self) { data in Text(data) .padding() } .onMove(perform: self.move) } } func move(from source: IndexSet, to destination: Int) { dataList.move(fromOffsets: source, toOffset: destination) } } |
Mac と iOS での動作の違い
Mac 上では、上記のコードだけで、リストの要素の入れ替えが可能となります。
iOS では、リストのスクロールとジェスチャーが重複していますので、明示的にエディットモードに入る必要があります。
エディットモードは、environment の .editMode で制御することができますので、iOS では、以下のようにすると並べ替え操作を行うことができます。
コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
struct ContentView: View { @State private var dataList = ["item1", "item2", "item3"] var body: some View { List { ForEach( dataList, id: \.self) { data in Text(data) .padding() } .onMove(perform: self.move) } .environment(\.editMode, .constant(.active)) // ⬅️ iOS 対応 } func move(from source: IndexSet, to destination: Int) { dataList.move(fromOffsets: source, toOffset: destination) } } |
上記では、常に active にしていますが、通常は、エディットモード切り替えをリストのタイトル部分等に表示して実装します。
まとめ:List の要素の並べ替えの実装方法のポイントは4つ
以下の点を考慮することで、非常に簡単に実装できます。
- ForEach の要素に対して、onMove を設定する
- onMove でデータソースのリスト要素の並べ替えを行う
- データソースが Array であれば、Array の move 関数を使うと非常に簡単に実装できる
- iOS であれば、.editMode を設定しないと、並べ替えモードにならない
説明は、以上です。
Sponsor Link