【Swift】Long Press Gesture Recognizerの使い方。部品の長押しを検知する。(Swift 2.1、XCode 7.2)

2020年6月16日

Long Press Gesture Recognizerとは

本記事ではSwiftで使える部品のLong Press Gesture Recognizer(以下、ロングプレスリコグナイザー)の使い方について説明する。

Long Press Gesture Recognizer

 

ロングプレスリコグナイザーとは、長押しを検知する部品である。似ている部品のTap Gesture Recognizer(以下、タップリコグナイザー)は指が画面に触れただけで検知されるので誤タップが起きやすい。

一方、ロングプレスリコグナイザーは検知までに一定時間が必要なので誤タップが起きにくい。ゆえに、誤タップしそうな状況を回避するために利用させることが多い。

マップビューの記事で、地図を長押しした位置にピンを刺す動きをロングプレスリコグナイザーを用いて実装しているので、そちらも参照されたし。⇒「記事

新宿駅

 

ロングプレスリコグナイザーを使ってみる

デバイス画面にラベルを配置する(下図赤矢印)。黄緑枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Colorに白、Backgroundに青色、User Interaction Enabledにチェックを入れる。

紫枠のアシスタントエディタボタンを押してViewController.swfitを開く。Ctrlキーを押しながらドラッグ&ドロップでラベルをソースコードまで運んで吹き出しの設定画面を表示させる。

Connectionに「Outlet」、Nameに「testsLabel」を入力してConnectボタンを押す。これでソースコードでラベルを操作できるようになった。

デバイス画面にラベルを配置する。

 

ロングプレスリコグナイザーをラベルに配置する(下図赤矢印)。Ctrlキーを押しながら黄緑枠のロングプレスリコグナイザーをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。

Connectionに「Action」、Nameに「pressLabel」、Typeに「UILongPressGestureRecognizer」を入力してConnectボタンを押す。これで長押しのイベントをソースコードで受けれるようになった。

Long Press Gesture Recognizerをラベルに配置する

 

ViewController.swiftを以下のコードに変更する。

「長押し時の呼び出しメソッド」は長押し開始と終了の2回呼び出されるので、ステータスから開始と終了を判別し、ラベルに表示している。

 

以下は実際のプレイ動画

ロングプレスリコグナイザーの設定

ロングプレスリコグナイザーのアトリビュートインスペクタを確認する。

Long Press Gesture Recognizerのアトリビュートインスペクタ

 

設定項目は以下の4項目で、すべての条件をクリアすると長押しと判定される。

設定名 説明
1 Min Duration 長押しと判定されるまでの時間の長さ。例えば「2.5」に設定すると、指が部品に触れてから2.5秒後に「長押し開始」が通知される。
2 Taps 長押し前のタップ数。例えば「3」に設定すると、部品を3タップしたあとの4タップ目を部品に触れたままにする。
3 Touches 長押し時の指の数。例えば「2」に設定すると、同時に2本の指で部品を触る。
4 Tolerance 指が画面に触れたあとの移動可能範囲をポイントで指定する。例えば「30」に設定すると、指が部品に触れてから半径約1cmまで指がズレても長押し判定に影響はない。

 

以下の動画はMin Durationを「2.5」、Tapsを「3」、Touchesを「2」、Toleranceを「200」に設定したときのプレイ動画

 

タップリコグナイザーと合わせた場合どうなるか

ロングプレスリコグナイザーと似ている部品といえばタップリコグナイザー。2つの部品の大きな違いは押している時間の長さである。この2つのリコグナイザーを1つの部品に配置した場合はどうなるかを確かめてみよう。

タップリコグナイザーをラベルに配置する(下図赤矢印)。水色枠のアシスタントエディタボタンを押してViewController.swiftを開く。Ctrlキーを押しながら紫枠のタップリコグナイザーをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。

Connectionに「Action」、Nameに「tapLabel」、Typeに「UITapGestureRecognizer」を入力してConnectボタンを押す。これでラベルをタップしたときのイベントをソースコードで受けれるようになった。

Tap Gesture Recognizerをラベルに配置する。

 

ViewController.swiftを以下のコードに変更する。「タップ時の呼び出しメソッド」でラベルの背景色をランダムな色に変更している。「長押し時の呼び出しメソッド」は変更なし。

 

以下は実際のプレイ動画。「長押し時の呼び出しメソッド」が実行されたときは「タップ時の呼び出しメソッド」は実行されなかった。つまり、長押しにならなかった場合のみタップと判定されるということだ。

 

ちなみに、「長押し時の呼び出しメソッド」が呼ばれたときに「タップ時の呼び出しメソッド」も呼んでほしい場合の実装方法は以下になる。

Ctrlキーを押しながら下図赤枠のロングプレスリコグナイザーをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。Connectionに「Outlet」、Nameに「longPressRecognizer」を入力しConnectボタンを押す。

黄緑枠のタップリコグナイザーも同様にして吹き出しの設定画面を表示し、Connectionに「Outlet」、Nameに「tapRecognizer」を入力しConnectボタンを押す。これでロングプレスリコグナイザーとタップリコグナイザーをソースコードで操作できるようになった。

Long Press Gesture RecognizerとソースコードをOutlet接続する

 

ViewController.swiftを以下のコードに変更する。デリゲートメソッドの「リコグナイザーの同時検知を許可するメソッド」を実装して、2つのリコグナイザーの検知が同時に行われるようにした。

 

以下は実際のプレイ動画。長押しとタップの両方の処理が実行されるようになった。

ただし、部品を押している時間が長いとタップリコグナイザーがタイムアウトして実行されない。なので、時間の長さで実行処理を振り分けるならロングプレスリコグナイザーを複数登録する作りにしたほうが良さそうだ。