Swift Playgroundsで学ぶiOSプログラミング

フリック操作で前のページに戻る機能を実装する

文●柴田文彦 編集●吉田ヒロ

2017年03月06日 17時00分

iOSの「ジェスチャー認識」機能を利用する

 iOSの特徴的なユーザーインターフェースとして、画面に指で触れて操作するジェスチャーが挙げられます。これは、ボタンに代表されるコントロール類を画面に配置していなくても、画面のどこを触っても操作できるという特徴があります。ただ、それだけに操作は大雑把なものとなりがちなので、適する用途とそうでないものがあります。それでも今回の目的である「戻る」動作には、ぴったりのようにも思えます。

 iOSのジェスチャー認識機能は、UIGestureRecognizerというクラスに定義されています。しかし、実際に利用する際には、そのクラスのオブジェクトを直接使うことはないでしょう。このクラスはジェスチャー認識機能の基礎となるもので、そこからジェスチャーの種類ごとに派生したクラスを使うことになります。現在では、次の7種類のクラスが用意され、それぞれ認識できるジェスチャーを受け持っています。

ジェスチャー認識のための基礎クラスUIGestureRecognizerは、ジェスチャーの種類ごとに分かれた合計7種類のサブクラスを持っています

UITapGestureRecognize タップ操作を認識する。何本に指でタップするのかをあらかじめ設定しておく。
UIPinchGestureRecognizer 2本指によるピンチイン/ピンチアウトの操作を認識する。通常はズームイン/ズームアウトの処理に対応させる。
UIRotationGestureRecognizer 2本指による回転の操作を認識する。2本の指が、同じ円の円周上を反対向きに動くと反応する。
UISwipeGestureRecognizer スワイプ動作を認識する。何本の指でスワイプするかと、上下左右のどの方向に反応するかを、あらかじめ設定しておく。
UIPanGestureRecognizer パン(ドラッグ)操作を認識する。何本の指での操作に反応するかは、最小と最大の指の本数を別々に指定して、範囲を絞ることができる。
UIScreenEdgePanGestureRecognizer 画面の端でのパン操作を認識する。通常はビューの切り替えなどに利用する。画面の上下左右のどの端部での操作に反応するかを設定しておく。
UILongPressGestureRecognizer 長押しの操作を認識する。何本の指で操作するか、何秒以上押し続けるか、押した指の動きをどこまで許容するかといった検出条件を指定できる。

 今回は、このうちスワイプ動作を認識するUISwipeGestureRecognizerを使います。ジェスチャー認識機能は、こうした○○GestureRecognizerクラスのオブジェクトを作成し、認識条件などを設定したあと、ジェスチャーを認識させる目的のビューに貼り付けるかたちで使います。ちょうど画面の上に、ジェスチャーセンサーのような透明のシートを貼り付けるイメージです。

 では、ジェスチャーを認識したことは、どうやって知ることができるのでしょうか。そのためには、ジェスチャー認識オブジェクトを作る際に、認識したら呼び出すメソッドを指定しておきます。あとはただ待っていれば、ユーザーが該当するジェスチャー操作をするたびに、何もしなくてもそのメソッドが呼び出されます。これは一種のコールバックです。

 ジェスチャー認識オブジェクトを作成したり、ジェスチャーが認識されるたびに呼び出されるメソッドは、ジェスチャー認識オブジェクトを張り付けるビューのビューコントローラーの中に記述するのが普通です。それを可能にするためには、既存のUIViewControllerクラスを拡張するクラスを記述する必要があります。

WebViewなど、目的のビューを作成する処理に加えて、ジェスチャー認識オブジェクトを作成してビューに張り付ける処理、ジェスチャーに応答するメソッドも、ビューコントローラーの中に記述します

カスタマイズ可能なビューコントローラーの準備

 前回に示したウェブブラウザーもどきのプログラムでは、コードの量を極小化するために、思い切って簡潔な方法を採用しました。それは、UIViewControllerは拡張せずにそのまま使い、そこに、これもそのままのウェブビューをはめ込んで表示しするという方法でした。これでもウェブサイトは表示できるのですが、そのままではジェスチャー認識機能を加えるようなカスタマイズができません。

 そこで今回は、まずウェブビューをはめ込むビューコントローラーを作成し、そこにさらにジェスチャー認識機能を貼り付けることにします。その前半のウェブビューをはめ込むビューコントローラーのプログラムは、実はウェブビュー(WKWebView)の公式なリファレンスページに、具体的な例が示されています。これは、ほとんどそのまま、Swift Playgroundsで利用できる基本的なコードです。まずはこれを参考に、ウェブビューを作成する部分のコードを書き直しましょう。

ウェブビューを含むビューコントローラーをカスタマイズするために、独自のPGViewControllerクラスを定義します

 ここでは、リファレンスページにあるものを、特に支障ない範囲でさらに簡略化しています。機能は前回に示したものと同じで、動かすと最初にグーグルの検索ページが開きます。

ビューコントローラーにジェスチャー認識機能を追加する

 ビューコントローラー内にジェスチャー認識機能を記述するには、大きく2つのステップが必要になります。

 1つめは、ジェスチャー認識機能のオブジェクトを新たに作成し、それをビューコントローラーのビューに張り付けるステップです。認識オブジェクトを作成する際には、ジェスチャーを認識した際に呼び出すメソッドを指定します。その後、ジェスチャー認識機能のオプションを指定してからビューに張り付けます。

 2つめのステップは、認識オブジェクトを作成する際に指定したメソッドを記述することです。その中では、そのジェスチャーによって実現したい機能を記述します。

 実際のコードを見てみましょう。まず最初のステップ、ジェスチャー認識オブジェクトの作成部分です。ここではpgSwipeという名前のジェスチャー認識オブジェクトを作成しています。

let pgSwipe = UISwipeGestureRecognizer(target: self, action:
#selector(self.handleSwipe(_:)))
pgSwipe.direction = .left
pgSwipe.numberOfTouchesRequired = 2
view.addGestureRecognizer(pgSwipe)

 Swift 3に特有の細かな文法については今回は説明しませんが、これでジェスチャーが認識された際に呼び出すメソッドにhandleSwipeを指定してオブジェクトを作成しています。それから、スワイプの方向を左にスワイプする際に画面に触れる指の数を2に設定し、addGestureRecognizerメソッドを使ってビューに認識オブジェクトを貼り付けています。

 次に、ジェスチャー認識後に呼び出されるメソッドです。

func handleSwipe(_ sender: UISwipeGestureRecognizer) {
  webView.goBack()
}

 この中では、ウェブビューのメソッドgoBackを呼び出しているだけです。これが「戻る」機能を実現するものです。

 最初に示した、カスタムなビューコントローラーを作成しウェブビューを配置するコードと、ジェスチャー認識オブジェクトを作成してビューに貼り付け、ジェスチャーに対する処理を実行するコードを合体しましょう。

PGViewControllerクラスのloadViewメソッドの中で、ウェブビューの作成に続いて、ジェスチャー認識オブジェクトを作成し、ビューに張り付けています。また、認識に応答するメソッドhandleSwipeも記述しています

 上のジェスチャーに関するコードは、すべて、カスタムなビューコントローラー、PGViewControllerのクラス定義の中に書いてあります。この図にはフレームワークをインポートする部分が含まれていませんが、次の図で確認してください。必要なフレームワークは前回と同じです。ジェスチャー認識のためのUIGestureRecognizerとそこから派生した具体的なクラスはすべてUIKitに含まれているため、新たなフレームワークをインポートする必要はありません。

 ジェスチャーの働きを画面ショットで示すことはできませんが、2本指で左方向にスワイプすることで「戻る」機能が働き、最初の画面に戻ってくることができるようになりました。

実際に動かしてみても、ジェスチャー認識機能があることは画面からはわかりません。しかし、2本指で左にスワイプすることでいつでも「戻る」機能が利用できます

 他の種類のジェスチャー認識機能を追加してみるなど、いろいろと試してみてください。ちなみにウェブ閲覧の履歴を先に「進む」機能は、ウェブビューのgoForward、リロードはreloadメソッドで実現できます。

次回の予定

 今回は、ジェスチャーを使ってウェブブラウザーのページ履歴を「戻る」機能を実現しました。次回は任意のURLを入力して、そこにジャンプさせる機能に挑戦します。これも、いろいろな方法が考えられますが最も簡潔な方法を追求します。

mobileASCII.jp TOPページへ

mobile ASCII

Access Rankingアクセスランキング