【Swift】タップ、ロングプレス処理を実装する！

# はじめに
アプリ開発していく中で、タップ・ロングプレスといったジェスチャーを使用しました。そこで今回はタップ・ロングプレスジェスチャー時にどうやって処理を実行させるかについてまとめます。

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

# スマホのジェスチャーを使うには？
Swiftでは、`UIGestureRecognizer`を用いることで様々なジェスチャーを用いた処理を実装することができる。
ジェスチャーの種類は下記のように色々あります。

- Tap（DoubleTap）
- Swipe
- Pinch
- Rotate
- LongPress
- Pan（Drag）

Apple公式ドキュメント：[UIGestureRecognizer](https://developer.apple.com/documentation/uikit/uigesturerecognizer)

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



# タップを用いた処理
タップを認識するためには、`UITapGestureRecognizer`を使用します。

全体のコードはこちら

```swift
import UIKit

//UIGestureRecognizerDelegateを追加する
class ViewController: UIViewController, UIGestureRecognizerDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //シングルタップ用のインスタンスを生成する
        let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(
            target: self,
            action: #selector(ViewController.singleTap(_:))
        )
        
        //デリゲートをセット
        tapGesture.delegate = self
        
        //viewにタップジェスチャーを追加
        self.view.addGestureRecognizer(tapGesture)
        
    }

    //シングルタップ時に実行されるメソッド
    @objc func singleTap(_ sender: UITapGestureRecognizer) {
        if sender.state == .ended {
            //ここに、タップ終了時に実行したい処理を記載する
        }
    }
}
```


# 解説

```swift
//シングルタップ用のインスタンスを生成する
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(
    target: self,
    action: #selector(ViewController.singleTap(_:))
)
```

シングルタップ用のUITapGestureRecognizerインスタンスを生成しています。
生成時に、ターゲットとタップ時に実行するメソッドを指定しています。

[Apple公式ドキュメント init(target:action:)](https://developer.apple.com/documentation/uikit/uigesturerecognizer/1624211-init)

---

 ```swift        
//viewにタップジェスチャーを追加
self.view.addGestureRecognizer(tapGesture)
```
コメントの通り、viewにタップジェスチャーを追加しています。これによって、viewがタップされた時に指定の処理が実行される。

---

```swift
//シングルタップ時に実行されるメソッド
@objc func singleTap(_ sender: UITapGestureRecognizer) {
    if sender.state == .ended {
        //ここに、タップして離した際に実行したい処理を記載する
    }
}
```

UITapGestureには、様々なプロパティが実装されていてその中に`state`プロパティがあります。ここではどんなstateプロパティがあるかだけ紹介します。詳細は公式ドキュメントでご確認お願いします。

- possible
- began
- changed
- ended
- cancelled
- failed

[Apple公式ドキュメント UIGestureRecognizer.State](https://developer.apple.com/documentation/uikit/uigesturerecognizer/state)

今回は、`sender.state == .ended`とすることでタップジェスチャー終了時に指定の処理を実行するようにしています。

### `@objc`や`#selector`ってなんぞや？
`@objc`はメソッドを定義する際につけることで、Objective-Cのメソッドとして認識されるとのこと。
ではなぜObjective-Cのメソッドとして認識する必要があるのか？

target-actionはObjective-Cで実装された仕組みで、target-actionで指定するのはObjective-Cのメソッドである必要がある。そのため、メソッド定義時は`@objc`をつけている。

また、Swiftでは`#selector`によってObjective-Cのメソッドを指定できるとのこと。



参考サイト：[#selector、@objc とターゲット-アクション](https://swift-ios.keicode.com/ios/target-action.php)





# ロングプレスを用いた処理
先ほどのタップを用いた処理を基本的には同じです。

```swift
override func viewDidLoad() {
    super.viewDidLoad()

    //ロングプレス用のインスタンスを生成する
    let longPressGesture = UILongPressGestureRecognizer(
        target: self,
        action: #selector(ViewController.longPress(_:))
    )
        
    //デリゲートをセット
    longPressGesture.delegate = self
        
    //viewにロングプレスジェスチャーを追加
    self.view.addGestureRecognizer(longPressGesture)
}
    
//ロングプレス時に実行されるメソッド
@objc func longPress(_ sender: UILongPressGestureRecognizer) {

    if sender.state == .ended {
        //ロングプレス終了時に実行したい処理を記載する
    }
}
```

解説もシングルタップと同じなので割愛します。
※ロングプレスのインスタンスを生成する部分で、`UILongPressGestureRecognizer`である点だけ違います。


# まとめ
今回はタップ、ロングプレス処理を実装するにあたり学習したことをまとめました。
想像以上に簡単に実装できて驚きました。まだ理解は浅いため、ドキュメントなどを再度読み込み理解を深めていきたいと思います。

以上。