【Swift】UIGestureRecognizerとは?UIKitでタップイベントを取得する方法!

この記事からわかること
- SwiftのUIKitでタップイベントを取得する方法
- ジェスチャーやジェスチャーレコグナイザーとは?
- UIGestureRecognizerクラスの使用方法
- UITapGestureRecognizer/UILongPressGestureRecognizerの使用方法
- 長押し/パン/ピンチの操作方法
- UIViewをサイズ変更させたり移動させるには?
index
[open]
- Gesture(ジェスチャー)とは?
- UIGestureRecognizerクラス
- ジェスチャーレコグナイザーの種類
- ジェスチャーの登録方法
- タップ:UITapGestureRecognizer
- 1.動作させたいジェスチャレコグナイザークラスを定義
- 2.ジェスチャー発生時に実行する処理を定義
- 3.Viewとの紐付け
- 長押し:UILongPressGestureRecognizer
- ピンチ:UIPinchGestureRecognizer
- ピンチされたViewを拡大/縮小させる機能
- UIView.transform
- パン:UIPanGestureRecognizer
- UIGestureRecognizer.State
- 全体のコード
\ アプリをリリースしました /
SwiftのUIKitでタップや長押しなどのイベントをビューに追加する方法をまとめました。
Gesture(ジェスチャー)とは?
Web制作では「イベント」と呼ばれるクリックやホバーなどのユーザー操作ですがSwiftではGesture(ジェスチャー)と呼ばれ管理されています。
ジェスチャーにはタップや長押し、スワイプ、ピンチなど、スマホを操作する際に発生するイベントが含まれています。
Swiftではジェスチャーが発生した時に任意の処理を行わせる仕組みが備わっているのです。これは元々イベント処理を持っているボタンなどだけではなく、Textやラベルなど本来イベント処理を保持していないビューに対してもカスタマイズして組み込むことが可能になります。
ジェスチャーに対する処理の組み込みはSwift UIではモディファイア(メソッド)として、UIKitではGestureRecognizer(ジェスチャーレコグナイザー)クラスとして用意されています。しかし両者は別物なので取扱には注意してください。
UIGestureRecognizerクラス
公式リファレンス:UIGestureRecognizerクラス
UIKitのジェスチャー管理の大元はUIGestureRecognizer
クラスです。このクラスを継承してタップを検知するUITapGestureRecognizer
やピンチを検知するUIPinchGestureRecognizer
などが定義されています。
ちなみに「Recognizer」とは「認識者」という意味です。
UIGestureRecognizerクラスにはデリゲートを使用するためのdelegate
プロパティやジェスチャージェスチャレコグナイザーの現在の状態を示すstateプロパティ、以下のような引数を保持するイニシャライザなどを保持しています。
ジェスチャーレコグナイザーの種類
UIGestureRecognizer
クラスを継承したサブクラスとしてさまざまな種類のジェスチャーレコグナイザーが用意されています。
クラス | 概要 |
---|---|
UITapGestureRecognizer | タップ |
UIPinchGestureRecognizer | ピンチ |
UIRotationGestureRecognizer | 画面回転 |
UISwipeGestureRecognizer | スワイプ(※) |
UIPanGestureRecognizer | パン(※) |
UIScreenEdgePanGestureRecognizer | 画面の端付近で始まるパン |
UILongPressGestureRecognizer | 長押し |
UIHoverGestureRecognizer | ホバー |
※:スワイプとパンは似たような動作(画面を指でスライドさせる)を表します。正確にはスワイプはタップ地点から直線方向のスライド、パンはタップ地点からあらゆる方向のスライドを検知するようです。スワイプレコグナイザーとパンレコグナイザーは競合してしまうため取り扱いには注意が必要です。
ジェスチャーの登録方法
ジェスチャーはビューに対して登録する形で使用していきます。ここでいうビューとはUIButton
やUILabel
といった全てのビュークラスです。
公式リファレンス:addGestureRecognizerメソッド
UIKitのビュークラスの大元であるUIView
クラスが持つaddGestureRecognizer
メソッドを使用することでそのビューに対してジェスチャーを登録することができます。
引数には登録したいUIGestureRecognizerクラスを渡します。
ジェスチャーの登録の流れ
- 動作させたいジェスチャレコグナイザークラスを定義
- ジェスチャー発生時に実行する処理を定義
- 実装させるビューからaddGestureRecognizerメソッドを呼び出して紐付ける
タップ:UITapGestureRecognizer
まずはUITapGestureRecognizer
使用してタップされた時の処理を実装をしていきます。まずはサンプル用のUIViewControllerクラスを用意しておきます。
1.動作させたいジェスチャレコグナイザークラスを定義
まずはUITapGestureRecognizer
インスタンスを生成します。引数にはターゲットとなるオブジェクト(今回はself)とイベント発生時に実行させたいメソッド名を#selectorを使用して指定します。Objective-Cの仕組みである#selector
で指定するメソッド側には@objc
の付与が必要になります。
おすすめ記事:【Swift UIKit】#selectorとは?使い方と@objcとsenderの意味まとめ
2.ジェスチャー発生時に実行する処理を定義
続いて実行時のメソッドを定義していきます。メソッドの定義前には@objc
の付与し、引数には指定したUIGestureRecognizer
型を受け取るようにしておきます。今回はタップイベント時のメソッドなのでメソッド名はtapped
にしておきました。
3.Viewとの紐付け
最後に定義したGestureRecognizerインスタンスをView
と紐付けていきます。今回はボタンではなくUIViewに紐付けてみたいと思います。シミュレーターでビルドしても何も表示されませんがタップすると処理が実行されるのを試してみてください。
self.view
からaddGestureRecognizer
メソッドを呼び出し、引数に先ほど定義したインスタンスを渡します。これで実装は完了です。
このようにUIGestureRecognizer
を使ったジェスチャー検知はView側への追加とメソッドの定義だけで簡単に実装できます。ここからは他のジェスチャー処理も見ていきます。
長押し:UILongPressGestureRecognizer
長押しされた時の処理を実装するにはUILongPressGestureRecognizer
を使用します。先ほどのようにインスタンスの生成とビューへの追加、処理メソッドを定義すればOKです。
これで長押し時に処理が実行されるようになりました。
ピンチ:UIPinchGestureRecognizer
ピンチされた時に処理を実行させるにはUIPinchGestureRecognizer
を使用します。次は新たにUIViewプロパティを定義してピンチされた時にそのサイズを変更させてみます。ピンチ処理の登録方法は今までと同じです。
ピンチされたViewを拡大/縮小させる機能
ピンチされたViewを拡大/縮小させる機能を実装するには場合は以下のように変換情報(アフィン変換※)を保持するtransform
プロパティを操作します。
※:アフィン変換とは図形を引き伸ばしたり回転させたりすること。
UIView.transform
Viewを実際に変化させるのは上記の部分です。UIViewのいくつかのプロパティは値を変化させることでアニメーションが可能になっておりtransform
もその1つです。transform
プロパティが準拠しているCGAffineTransform
構造体の持つscaledBy
メソッドを呼び出してViewに格納しスケールを変化させます。
パン:UIPanGestureRecognizer
パン(指をスライド)させた時に処理を実装させるにはUIPanGestureRecognizer
を使用します。例えばビューパンした位置へ移動させるには以下のように実装します。
transform(in:)
メソッドで変化した位置量の情報を取得して初期位置と計算しcenter
に設定することでビューを配置し直しています。
UIGestureRecognizer.State
UIGestureRecognizerクラスのStateプロパティはジェスチャージェスチャレコグナイザーの現在の状態を取得できます。
全体のコード
Storyboardは使用していないのでそのままコピペするだけで動作します。
おすすめ記事:【Swift/UIKit】コードからビューのタップイベントを発行する方法!sendActions
おすすめ記事:【Swift/UIKit】タップした座標(位置)を取得する方法!touchesBegan
おすすめ記事:【Swift/UIKit】UIViewでタップイベントなどを無効にする方法!isUserInteractionEnabled
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。