Listの行を並び替える方法【SwiftUI】

前回の記事でListの行を削除する方法を紹介しましたが、今回はドラッグ操作で並び替えをする方法について書きたいと思います。

onMoveアクション

前回のonDeleteと同じく、ForEachに組み込まれているonMoveアクションを利用します。

また、前回には無かった、編集ボタン(EditButton)をナビゲーションバーに追加します。

struct ContentView: View {
    
    @State private var languages = [
        "C/C++",
        "Java",
        "C#",
        "Ruby",
        "PHP",
        "Objective-C",
        "Swift",
        "Kotlin",
        "Python"
    ]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(languages, id: \.self) { lang in
                    Text(lang)
                }
                .onMove(perform: { (source, destination) in
                    self.languages.move(fromOffsets: source, toOffset: destination)
                })
            }
            .navigationBarItems(trailing: EditButton())
        }
    }
}

onMoveperform: 引数は以下のフォーマットに従う必要があります。

(from source: IndexSet, to destination: Int) -> Void

上記ではコードでは、クロージャで実現していますが、フォーマットに従っていれば別メソッドを定義して、それを引数に与えることも出来ます。

var body: some View {
    NavigationView {
        List {
            ForEach(languages, id: \.self) { lang in
                Text(lang)
            }
            .onMove(perform: move)
        }
        .navigationBarItems(trailing: EditButton())
    }
}

func move(from source: IndexSet, to destination: Int) {
    self.languages.move(fromOffsets: source, toOffset: destination)
}

また、ナビゲーションバーに編集ボタン(EditButton)を追加します。これが無いと並び替えモードに移ることが出来ませんので忘れずに。

NavigationView {
    List {
        省略
    }
    .navigationBarItems(trailing: EditButton())
}

以上、SwiftUIでListの並び替えをする方法でした。