スワイプアクションを実装する

Swipeメニューを実装する方法 3つ
# 共通
これは実装してないといけない

```swift
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
```

# iOS 2.0+
昔からあるやつ。
使いにくい。削除くらいしかアクション選択肢がない。

```swift
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath)

//関連メソッド
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle
```

# iOS 8.0+
「←」向きのアクションしか設定できません。

```swift
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
```

## 例

```swift
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?{
    let seasonData = childdata as! Season
    let delete = UITableViewRowAction(style: .default, title: "削除"){(action, indexPath) -> Void in
        //削除処理
    }
    //------
    let share = UITableViewRowAction(style: .normal, title: "共有"){(action, indexPath) -> Void in
        // 処理
    }
    share.backgroundColor = UIColor.blue //自由に色を決められる
    //------
    return [delete, share]
}
```

結果はこんな感じ
　　　　↓青　↓赤
━━━━━━━━━━
　　　┃共有┃削除┃
━━━━━━━━━━

.backgroundColorを設定していなければ、標準の灰色になります。

# iOS 11.0+

```swift
//←
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?

//→
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
```

両サイドからのスワイプアクションを設定できます。
こちらのメソッドを使うと、フルスワイプ時に1つ目のアクションを実行できるようになります。

## 実装方法
両関数の返り値は`UISwipeActionsConfiguration?`型なので、`UISwipeActionsConfiguration`の`init`を確認します。

```swift
UISwipeActionsConfiguration(actions: [UIContextualAction])
```

`[UIContextualAction]`を作れば良いことがわかるので、`UIContextualAction`のinitを見ます。

```swift
UIContextualAction(
    style: UIContextualAction.Style,
    title: String?,
    handler: UIContextualActionHandler)
```

また、

```swift
public typealias UIContextualActionHandler = (UIContextualAction, UIView, (Bool) -> Swift.Void) -> Swift.Void
```

より、

```swift
let action = UIContextualAction(
    style: UIContextualAction.Style,
    title: String?){ (action, sourceView, completionHandler) -> Void in
        //処理
    }
```

という風に書けば良いことがわかります。
UIContextualActionHandlerの引数は、それぞれ

 - action: 選択されたアクションに関する情報を含むオブジェクト
 - sourceView: アクションが表示されたビュー
 - completionHandler: アクションを実行した後に実行するハンドラブロック。 このブロックには戻り値がなく、次のパラメータが使用されます。
    - actionPerformed:
アクションを実行したかどうかを示すブール値。 アクションが実行できた場合はtrueを指定し、何らかの理由でアクションを実行できなかった場合はfalseを指定します。

参考 [UIContextualActionHandler - UIKit | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uicontextualactionhandler)

**アクションを実行した後にcompletionHandlerを実行しないといけません！**
**completionHandlerの引数はtrue or false アクションの実行が成功したかどうか**

これを順番に実装していけば次のようになります。

```swift
@available(iOS 11.0, *)
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let delete = UIContextualAction(
        style: .destructive,
        title: "削除"){ _,_,handler in
            //処理
            handler(true)
    }

    let share = UIContextualAction(
        style: .normal,
        title: "共有"){ _,_,handler in
            //処理
            handler(true)
    }
    share.backgroundColor = UIColor.blue
    
    let configuration = UISwipeActionsConfiguration(actions: [delete, share])
    configuration.performsFirstActionWithFullSwipe = true //falseにすると、フルスワイプしてもアクションが実行されなくなる
    return configuration
}
```

中身はleadingの場合でも同じです。