【Swift UI】Listの行の順番を入れ替える方法!onMoveの使い方
この記事からわかること
- Swift UIのList構造体で行を入れ替える方法
- 順番を変更するには?
- ForEachのonMoveの使い方
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
Listの行の順番を入れ替える方法
Swift UIでList
で行の順番を入れ替えるにはForEach
のonMove
を使用します。List
だけで表示している場合はonMove
が使用できないので注意してください。今回はシンプルな配列を渡し、移動された時に実際の配列データの中身も操作してみます。
ポイント
- Listの中でForEachを利用する
- 配列にはidが必要
- Listを編集モードにするためにEditButtonが必要
struct ContentView: View {
@State var langs = ["Swift", "Kotlin", "Objective-C", "Java", "Dart"]
var body: some View {
NavigationStack {
List {
ForEach(langs, id: \.self) { lang in
Text(lang)
}.onMove { sourceSet, destination in
// 配列の中身も移動
langs.move(fromOffsets: sourceSet, toOffset: destination)
}
}.toolbar { EditButton() }
}
}
}
toolbar
にEditButton
を付与することで画面上部に編集ボタンが追加されList
のモードを編集モードに切り替えることができるようになります。編集モードになると行の右側に移動させるようのアイコンが表示されます。
アイコンをタッチしながら上下にスライドさせることで並んでいる行の順番を変更させることが可能です。
またわざわざEditButton
を付与せずとも行を長押ししてそのままスライドさせることで移動させることも可能です。
ちなみにこの編集モードは環境変数EditMode
から参照することが可能です。
onMoveメソッド
func onMove(perform action: Optional<(IndexSet, Int) -> Void>) -> some DynamicViewContent
行が移動したことを検知するとonMove
が呼ばれます。引数からIndexSet
型で移動前の位置を、Int
型で移動後の位置を取得することができます。
.onMove { sourceSet, destination in
print("source:\(sourceSet.first!)")
print("destination:\(destination)")
}
取得できる移動位置情報
ですが取得できるデータ型が異なることで移動前の位置を移動後の位置の数値には少しクセがあります。移動した際に格納される値を実際に見てみます。現在の配列の中身は以下とし、毎回以下の状態から移動させたとします。
Swift
Kotlin
Objective-C
Java
Dart
上→下
上→下に移動させる場合はsource
に配列の元要素番号(0始まり)が、destination
に表示されている順番の番号(1始まり)が入るようです。
Swiftを2番目に(上→下)
Kotlin
Swift
Objective-C
Java
Dart
source:0
destination:2
Swiftを5番目に(上→下)
Kotlin
Objective-C
Java
Dart
Swift
source:0
destination:5
Kotlinを4番目に(上→下)
Swift
Objective-C
Java
Kotlin
Dart
source:1
destination:4
下→上
下→上に移動させる場合はsource
もdestination
に移動元と移動先の配列の要素番号(0始まり)が入るようです。
Kotlinを1番目に(下→上)
Kotlin
Swift
Objective-C
Java
Dart
source:1
destination:0
Dartを1番目に(下→上)
Dart
Swift
Kotlin
Objective-C
Java
source:4
destination:0
Objective-Cを2番目に(下→上)
Swift
Objective-C
Kotlin
Dart
Java
source:2
destination:1
色々と試してみましたが、両者ともに位置情報が0始まりか、1始まりか変化しているような感じになりました(?)。はっきり情報がわかったらまた更新したいと思います。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。