SwiftUI

[SwiftUI] リストアイテム を常に 移動 可能 にする

SwiftUI

SwiftUI において、リスト に登録した リストアイテム を 移動 する View を実装したかったのですが、 toolbar の EditButton を用いる実装では都度 Edit ボタン を クリック する必要があり、その手間を省けないかと思いました。 実装してみれば簡単なのですが、あまり サンプル も見つからなかったた事もあり、本記事で整理してみます。

Xcode: 12.4
Swift: 5

はじめに SwiftUI で リスト を実装

[ads]

まずは、単純なリストを実装するところから始めます。

import SwiftUI

struct ContentView: View {
    var body: some View {
        SampleList()
    }
}

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {
        ContentView()
    }
}

ContentView.swift

単純に5つの アイテム を生成し、 リスト に表示する シンプル な リスト です。

SampleList.swift

struct SampleList: View {

    struct Item: Identifiable {
        let id = UUID()
        let title: String
    }

    @State private var items: [Item] = (0..<5).map { Item(title: "Item #\($0)") }
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    Text(item.title)
                }
            }
        }
    }
}

EditButton を用いて、 リストアイテム を 移動 する

[ads]

まずは、EditButton を用いた実装を紹介します。 なお、ここで NavigationView を追加していますが、追加せずとも動作するはずです。

以下の サイト を参考に、下記を追記しています。

  • move function を定義
  • リストアイテム の onMove の Perform アクション の Closure として指定
  • リストの Modifier に toolbar を追加し、要素として EditButton を追加
EditButton | Apple Developer Documentation
A button that toggles the edit mode environment value.

SampleList.swift

struct SampleList: View {

    struct Item: Identifiable {
        let id = UUID()
        let title: String
    }

    @State private var items: [Item] = (0..<5).map { Item(title: "Item #\($0)") }
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    Text(item.title)
                }
                .onMove(perform: move)
            }
            .navigationTitle("Navigation Title")
            .toolbar {
                EditButton()
            }
        }
    }
    
    private func move(source: IndexSet, destination: Int) {
        items.move(fromOffsets: source, toOffset: destination)
    }
}

Editボタン を クリック することで、編集 モード になり、 リスト が移動できるようになります。


リストアイテム を常に 移動 できるようにする

[ads]

UI によっては、都度 Edit ボタン を クリック するのが煩雑な場合もあるかと思います。
次に紹介するのは、 リスト の アイテム が常に移動できるようになる サンプル です。

以下の サイト を参考に、以下を実装します。

  • リスト の environment Modifier の中で、 EditMode.active を指定

https://developer.apple.com/documentation/swiftui/environmentvalues
https://developer.apple.com/documentation/swiftui/editmode

SampleList.swift

struct SampleList: View {

    struct Item: Identifiable {
        let id = UUID()
        let title: String
    }

    @State private var items: [Item] = (0..<5).map { Item(title: "Item #\($0)") }
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    Text(item.title)
                }
                .onMove(perform: move)
            }
            .navigationTitle("Navigation Title")
            .environment(\.editMode, .constant(EditMode.active))
        }
    }
    
    private func move(source: IndexSet, destination: Int) {
        items.move(fromOffsets: source, toOffset: destination)
    }
}

このように、 Edit ボタン を クリック することなく、 リスト の アイテム が常に移動可能となります。


まとめ

[ads]
  • List の onMove モディファイア で move 部分を実装
  • Navigation View の environment モディファイア で \.editMode を指定することで 常に リスト を編集状態にすることが可能

関連記事

[ads]

その他参考にしたサイト

How to let users move rows in a list - a free SwiftUI by Example tutorial
Learn Swift coding for iOS with these free tutorials
Ads