iOS11 Swipe Actions

# はじめに

iOS11からスワイプアクションの実装が変わったようなので、
試してみました。

[Updating Your App for iOS 11](https://devstreaming-cdn.apple.com/videos/wwdc/2017/204kty9amomlmk/204/204_updating_your_app_for_ios_11.pdf)

![to.gif](https://qiita-image-store.s3.amazonaws.com/0/71694/daf37039-45d4-1a19-3801-c1d7372154d9.gif)


## iOS11での変更点

①UITableViewDelegateに「Swipe actions」関連のメソッドが追加されました。

```swift:UITableView.h
// Swipe actions
// These methods supersede -editActionsForRowAtIndexPath: if implemented
// return nil to get the default swipe actions
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);
- (nullable UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(tvos);
```

|メソッド名　 | 説明 |
|---|---|
| leadingSwipeActionsConfigurationForRowAt | 左から右へスワイプしたときに呼ばれるメソッド|
| trailingSwipeActionsConfigurationForRowAt | 右から左へスワイプしたときに呼ばれるメソッド|

②その他関連クラス

|メソッド名　 | 説明 |
|---|---|
|UIContextualAction|ボタンのタイトル、アイコン、選択されたときのアクションを定義するクラス |
|UISwipeActionsConfiguration|UIContextualActionを束ねるクラス |

## サンプル
アクションを実行後、successメソッドの引数にtrueを指定すると、閉じます。
ボタンのデフォルトカラーは、lightGrayのようです。
　完成版は、[こちら](https://github.com/stv-ekushida/ios11-swipe-actions)

```swift:ViewController.swift
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {

    //左から右へスワイプ
    func tableView(_ tableView: UITableView,
                   leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

        let editAction = UIContextualAction(style: .normal,
                                            title:  "編集",
                                            handler: { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in
            success(true)
        })
        editAction.image = UIImage(named: "edit")
        editAction.backgroundColor = .blue

        let copyAction = UIContextualAction(style: .normal,
                                            title: "コピー",
                                            handler: { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in
            success(true)
        })
        copyAction.image = UIImage(named: "copy")

        return UISwipeActionsConfiguration(actions: [editAction, copyAction])
    }

    ///右から左へスワイプ
    func tableView(_ tableView: UITableView,
                   trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

        let moveAction = UIContextualAction(style: .normal,
                                            title:  "移動",
                                            handler: { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in
            success(true)
        })
        moveAction.image = UIImage(named: "move")
        moveAction.backgroundColor = .green

        let removeAction = UIContextualAction(style: .normal,
                                            title: "削除",
                                            handler: { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in
            success(true)
        })
        removeAction.image = UIImage(named: "trash")
        removeAction.backgroundColor = .red

        return UISwipeActionsConfiguration(actions: [removeAction, moveAction])
    }
}
```

## 参考
iOS10までの実装

```swift:ViewController.swift
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView,
                   editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        return addSwipeEvent()
    }

    /// セルのアクションを有効にする
    ///
    /// - Parameters:
    ///   - tableView: TableView
    ///   - indexPath: インデックスパス
    /// - Returns: 有効か？
    func tableView(_ tableView: UITableView,
                   canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    /// スワイプされたときの処理
    ///
    /// - Parameters:
    ///   - content: タイトル
    ///   - index: セルのインデックス
    func swipeContentsTap(content: String, index: Int) {
        print(index.description + "番のセル　→　" + "内容:" + content)
    }

    /// Swipeイベントを登録する
    ///
    /// - Returns: Swipeイベント一覧
    private func addSwipeEvent() -> [UITableViewRowAction]? {

        let swipeCellA = UITableViewRowAction(style: .default, title: "内容A") { _, index in
            self.swipeContentsTap(content: "CellA", index: index.row)
        }
        let swipeCellB = UITableViewRowAction(style: .default, title: "内容B") { _, index in
            self.swipeContentsTap(content: "CellB", index: index.row)
        }
        let swipeCellC = UITableViewRowAction(style: .default, title: "内容C") { _, index in
            self.swipeContentsTap(content: "CellC", index: index.row)
        }
        swipeCellA.backgroundColor = .blue
        swipeCellB.backgroundColor = .red
        swipeCellC.backgroundColor = .green

        return [swipeCellC, swipeCellB, swipeCellA] // A,B,Cという順で表示される
    }
}
```