【Swift】スワイプ処理を実装する

# はじめに
アプリ開発していく中で、スワイプジェスチャーを使用しました。そこで今回はスワイプジェスチャーについてまとめます。


# 開発環境
- macOS Catalina version10.15.7
- Xcode version12.2
- Swift5

# 様々なジェスチャー
Appleのヒューマンインターフェースガイドラインより、様々なジェスチャーの動画を確認できます。
[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/gestures/)

ガイドラインを見ていて、フリックとスワイプって何が違うのか？と思ったので調べてみました。

### フリックとスワイプの違いは？
フリック：画面を指で軽くはじくイメージ。文字入力などに使う。
スワイプ：画面に指を触れたままスライドさせるイメージ。画面遷移などに使う。

参考サイト：[「スワイプ」と「フリック」の違い・活用術　今さら聞けないスマホの基本操作](https://mag.app-liv.jp/archive/126446/)

確かにフリック入力って言いますね。（自分は文字入力はタップ入力に慣れてしまっているためイメージしにくかったのかも）

# スワイプ処理実装
全体のコード

```swift
import UIKit

//UIGestureRecognizerDelegateを追加する
class ViewController: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        //上スワイプ用のインスタンスを生成する
        let upSwipe = UISwipeGestureRecognizer(
            target: self,
            action: #selector(ViewController.didSwipe(_:))
        )
        upSwipe.direction = .up
        self.view.addGestureRecognizer(upSwipe)
        
        //右スワイプ用のインスタンスを生成する
        let rightSwipe = UISwipeGestureRecognizer(
            target: self,
            action: #selector(ViewController.didSwipe(_:))
        )
        rightSwipe.direction = .right
        self.view.addGestureRecognizer(rightSwipe)
        
        //下スワイプ用のインスタンスを生成する
        let downSwipe = UISwipeGestureRecognizer(
            target: self,
            action: #selector(ViewController.didSwipe(_:))
        )
        downSwipe.direction = .down
        self.view.addGestureRecognizer(downSwipe)
        
        //左スワイプ用のインスタンスを生成する
        let leftSwipe = UISwipeGestureRecognizer(
            target: self,
            action: #selector(ViewController.didSwipe(_:))
        )
        leftSwipe.direction = .left
        self.view.addGestureRecognizer(leftSwipe)

    }

    //スワイプ時に実行されるメソッド
    @objc func didSwipe(_ sender: UISwipeGestureRecognizer) {
        
        //スワイプ方向による実行処理をcase文で指定
        switch sender.direction {
        case .up:
            //上スワイプ時に実行したい処理
        case .right:
            //右スワイプ時に実行したい処理
        case .down:
            //下スワイプ時に実行したい処理
        case .left:
            //左スワイプ時に実行したい処理
        default:
            break
        }
    }
}
```

参考：[【Swift/UIKit】タップ・長押し・スワイプを認識させる](https://hirakana.hatenablog.jp/entry/2020/01/31/212238)

# 解説
スワイプ処理は、方向の指定箇所以外は同じ処理のためここでは上スワイプ処理のコードを使って簡単に説明します。

```swift
//上スワイプ用のインスタンスを生成する
let upSwipe = UISwipeGestureRecognizer(
    target: self,
    action: #selector(ViewController.didSwipe(_:))
)
upSwipe.direction = .up
self.view.addGestureRecognizer(upSwipe)
```

タップ、ロングプレスと同様に、まずはインスタンスを生成する。
その際に、スワイプジェスチャー時に実行したいメソッドを指定する。
メソッド指定時に`#selector`を使用している理由や、メソッド定義時に`@objc`は下記の通りです。

> target-actionはObjective-Cで実装された仕組みで、target-actionで指定するのはObjective-Cのメソッドである必要がある。そのため、メソッド定義時は@objcをつけている。
また、Swiftでは#selectorによってObjective-Cのメソッドを指定できるとのこと。
参考：[【Swift】タップ、ロングプレス処理を実装する！](https://qiita.com/sasao3/items/9f1b4a0b42f221923c5a)

<br>

```swift
upSwipe.direction = .up
```
directionよりスワイプの方向を指定する。
スワイプの方向は全部で4つ。`right`,`left`,`up`,`down`
[公式ドキュメント UISwipe Gesture Recognizer .Direction](https://developer.apple.com/documentation/uikit/uiswipegesturerecognizer/direction)

<br>

```swift
self.view.addGestureRecognizer(upSwipe)
```
`addGestureRecognizer()`でスワイプイベントをviewに追加しています。

<br>

```swift
//スワイプ時に実行されるメソッド
@objc func didSwipe(_ sender: UISwipeGestureRecognizer) {

    //スワイプ方向による実行処理をcase文で指定
    switch sender.direction {
    case .up:
        //上スワイプ時に実行したい処理
    case .right:
        //右スワイプ時に実行したい処理
    case .down:
        //下スワイプ時に実行したい処理
    case .left:
        //左スワイプ時に実行したい処理
    default:
        break
    }
}
```
各スワイプ時に実行する処理がこちらになります。
Switch文を用いて、スワイプの方向によって実行する処理を設定しています。

# 【おまけ】ジェスチャーを無効、有効化するには？
最初ジェスチャーの無効、有効化を調べていたところ下記コードでできるという記事を見つけました。

```swift
UIApplication.shared.beginIgnoringInteractionEvents() //無効化
UIApplication.shared.endIgnoringInteractionEvents() //有効化
```

しかし、実装してみたところ下記警告が出ました。
> beginIgnoringInteractionEvents()' was deprecated in iOS 13.0: Use UIView's userInteractionEnabled property instead

どうやら、iOS13より上記コードは非推奨になったらしいです。`userInteractionEnabled`を使ってくださいとのことでした。

`userInteractionEnabled`を用いた無効、有効化はこちらになります。


```swift
self.view.isUserInteractionEnabled = false //ジェスチャー無効
self.view.isUserInteractionEnabled = true //ジェスチャー有効（デフォルト値）
```

参考：[公式ドキュメント isUserInteractionEnabled](https://developer.apple.com/documentation/uikit/uiviewpropertyanimator/1648365-isuserinteractionenabled)

# まとめ
今回はスワイプ処理に関する学んだことをまとめました。
普段何気なく使っているスワイプ処理がこんな感じで実装されているんだなぁと知ることができて勉強になりました。

以上。