中学数学621382 views
中学英語808712 views
英語607877 views
小学理科717236 views
小学算数1194618 views
Computer365120 views
高校生物549842 views
LaTeX957300 views
高校日本史189857 views
高校倫理1433119 views
Help
Tools

English

スワイプアクション(swipeActions)

List の行をスワイプしてアクションボタンを表示する機能は、iOS アプリで広く使われている UI パターンです。SwiftUI では swipeActions モディファイアで簡単に実装できます。

基本的なスワイプアクション

swipeActions モディファイアを行に適用することで、スワイプ時に表示されるボタンを定義できます。

struct ContentView: View {
    @State private var items = ["項目1", "項目2", "項目3"]
    
    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text(item)
                    .swipeActions {
                        Button(role: .destructive) {
                            // 削除処理
                        } label: {
                            Label("削除", systemImage: "trash")
                        }
                    }
            }
        }
    }
}

デフォルトでは右から左へのスワイプ(trailing 側)でアクションが表示されます。

スワイプ方向の指定

edge パラメータで、左右どちらからスワイプしたときにアクションを表示するか指定できます。

Text(item)
    .swipeActions(edge: .leading) {
        Button {
            // ピン留め処理
        } label: {
            Label("ピン留め", systemImage: "pin")
        }
        .tint(.yellow)
    }
    .swipeActions(edge: .trailing) {
        Button(role: .destructive) {
            // 削除処理
        } label: {
            Label("削除", systemImage: "trash")
        }
    }
edge: .leading

左から右へスワイプしたとき(行の左側にボタン表示)

edge: .trailing

右から左へスワイプしたとき(行の右側にボタン表示、デフォルト)

複数のアクションボタン

複数のボタンを並べることも可能です。

Text(item)
    .swipeActions(edge: .trailing, allowsFullSwipe: false) {
        Button(role: .destructive) {
            // 削除
        } label: {
            Label("削除", systemImage: "trash")
        }
        
        Button {
            // アーカイブ
        } label: {
            Label("アーカイブ", systemImage: "archivebox")
        }
        .tint(.blue)
        
        Button {
            // フラグ
        } label: {
            Label("フラグ", systemImage: "flag")
        }
        .tint(.orange)
    }

allowsFullSwipe: false を指定すると、フルスワイプによる自動実行を無効にできます。

ボタンの色(tint)

tint モディファイアでボタンの背景色を変更します。role: .destructive を指定した場合は自動的に赤になります。

Button {
    // 処理
} label: {
    Label("お気に入り", systemImage: "heart")
}
.tint(.pink)

実践的な例:Todo リスト

struct Task: Identifiable {
    let id = UUID()
    var title: String
    var isCompleted: Bool
}

struct TodoListView: View {
    @State private var tasks = [
        Task(title: "買い物", isCompleted: false),
        Task(title: "掃除", isCompleted: true),
        Task(title: "洗濯", isCompleted: false)
    ]
    
    var body: some View {
        List {
            ForEach($tasks) { $task in
                HStack {
                    Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle")
                        .foregroundColor(task.isCompleted ? .green : .gray)
                    Text(task.title)
                }
                .swipeActions(edge: .leading) {
                    Button {
                        task.isCompleted.toggle()
                    } label: {
                        Label(
                            task.isCompleted ? "未完了に戻す" : "完了",
                            systemImage: task.isCompleted ? "arrow.uturn.backward" : "checkmark"
                        )
                    }
                    .tint(task.isCompleted ? .orange : .green)
                }
                .swipeActions(edge: .trailing) {
                    Button(role: .destructive) {
                        tasks.removeAll { $0.id == task.id }
                    } label: {
                        Label("削除", systemImage: "trash")
                    }
                }
            }
        }
    }
}

swipeActions は直感的な操作を可能にする重要な UI 要素です。削除のような破壊的な操作には role: .destructive を指定し、ユーザーに視覚的なフィードバックを与えましょう。