【Swift】Swipe Gesture Recognizerの使い方。上下左右のスワイプを検知する。(Swift 2.1、XCode 7.2)
Swipe Gesture Recognizerとは
本記事ではSwiftで使える部品のSwipe Gesture Recognizer(スワイプリコグナイザー)の使い方について説明する。
スワイプリコグナイザーとは、スワイプを検知する部品である。スワイプとは、画面に触れた指を上下左右いずれかの方向に素早く動かす動作のことをいう。
スワイプと似た言葉に「フリック」がある。「フリック」は画面内の部品に指を置いて上下左右いずれかの方向に弾く動作のことをいい、キーボード入力やスイッチ操作などの表現で使われる。
「スワイプ」は画面内の特定範囲に指を置いて上下左右いずれかの方向に弾く動作のことをいい、ページめくりやスクロールなどの表現で使われる。
Swiftではフリックもスワイプもスワイプリコグナイザーで実装するので、本サイトでは特に使い分ける必要がない限りスワイプと表現する。
スワイプリコグナイザーを使ってみる
実際にスワイプリコグナイザーを使ってみよう。ラベルをスワイプすると、方向がラベルに表示されるものを実装する。
デバイス画面にラベルを配置する(下図赤矢印)。黄緑枠のアシスタントエディタボタンを押してViewController.swiftを表示する。
Ctrlキーを押しながらラベルをソースコードまで運んで吹き出しの設定画面を表示させる(青矢印)。Connectionに「Outlet」、Nameに「testLabel」を入力しConnectボタンを押す。これでラベルをソースコードで操作できるようになった。
紫枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Colorに白、Backgroundに青、User Interaction Enabledにチェックを入れる。
スワイプリコグナイザーはスワイプする方向(上下左右)によってリコグナイザーを分ける必要があるので、仮に、上下左右の4方向のスワイプを検知したい場合は4つのスワイプリコグナイザーを登録しなければならない。
ストーリーボードで4回も登録するのが面倒なので、今回はソースコードでスワイプリリコグナイザーを登録する。
ViewController.swiftを以下のコードに変更する。4個のスワイプリコグナイザーの呼び出しメソッドは全て同じで、引数をもとにスワイプ方向を判別し、ラベルに表示している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// // ViewController.swift // import UIKit class ViewController: UIViewController{ @IBOutlet weak var testLabel: UILabel! //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() let directionList:[UISwipeGestureRecognizerDirection] = [.Up, .Down, .Right, .Left] for direction in directionList { //4方向のスワイプリコグナイザーをラベルに登録する。 let swipeRecognizer = UISwipeGestureRecognizer(target:self, action:Selector("swipeLabel:")); swipeRecognizer.direction = direction testLabel.addGestureRecognizer(swipeRecognizer) } } //スワイプ時の呼び出しメソッド func swipeLabel(sender:UISwipeGestureRecognizer) { //スワイプした方向をラベルに表示する。 switch(sender.direction){ case UISwipeGestureRecognizerDirection.Up: testLabel.text = "上" case UISwipeGestureRecognizerDirection.Down: testLabel.text = "下" case UISwipeGestureRecognizerDirection.Right: testLabel.text = "右" default: testLabel.text = "左" } } } |
以下は実際のプレイ動画。動画を見ると分かるように、指をゆっくり移動させるとスワイプリコグナイザーに検知されなくなる。
スワイプで部品を動かす
せっかくなので、スワイプの感じを出すためにスワイプした方向にラベルが移動するものを作ってみよう。
デバイス画面のラベルを選択したあとに、下図赤枠のAlignボタンを押して吹き出しの設定画面を表示させる。黄緑枠のHorizontally in ContainerとVertically in Containerにチェックを入れ、両方とも値を「0」にして「Add 2 Constraints」ボタンを押す。これでアプリ起動時にラベルが必ず画面中央に配置されるようになった。
次に紫枠のPinボタンを押して吹き出しの設定画面を表示する。WidthとHeightにチェックを入れて「Add 2 Constraints」ボタンを押す。これでラベルのサイズの制約が追加された。
下図黄緑枠の位置の制約(Test Label.centerY = centerY)をCtrlキーを押しながらドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。Connectionに「Outlet」、Nameに「yConstraint」を入力してConnectボタンを押す。
赤枠の位置の制約(Test Label.centerX = centerX)も同じように吹き出しの設定画面を表示させ、Connectionに「Outlet」、Nameに「xConstraint」を入力してConnectボタンを押す。これで位置の制約をソースコードから操作できるようになった。
ViewController.swiftを以下のコードに変更する。ラベルが画面の外に飛び出さないようにしながら、スワイプした方向にラベルをアニメーションで移動させている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
// // ViewController.swift // import UIKit class ViewController: UIViewController, UIGestureRecognizerDelegate{ @IBOutlet weak var testLabel: UILabel! @IBOutlet weak var xConstraint: NSLayoutConstraint! @IBOutlet weak var yConstraint: NSLayoutConstraint! //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() let directionList:[UISwipeGestureRecognizerDirection] = [.Up, .Down, .Right, .Left] for direction in directionList { //4方向のスワイプリコグナイザーをラベルに登録する。 let swipeRecognizer = UISwipeGestureRecognizer(target:self, action:Selector("swipeLabel:")); swipeRecognizer.direction = direction swipeRecognizer.delegate = self testLabel.addGestureRecognizer(swipeRecognizer) } } //スワイプ時の呼び出しメソッド func swipeLabel(sender:UISwipeGestureRecognizer) { //スワイプした方向に応じてラベルの制約を変更する。 switch(sender.direction){ case UISwipeGestureRecognizerDirection.Up: //画面の下半分にいれば上に移動する。 if(yConstraint.constant >= 0) { yConstraint.constant = yConstraint.constant - view.frame.size.height/2 + testLabel.frame.size.height/2 } case UISwipeGestureRecognizerDirection.Down: //画面の上半分にいれば下に移動する。 if(yConstraint.constant <= 0) { yConstraint.constant = yConstraint.constant + view.frame.size.height/2 - testLabel.frame.size.height/2 } case UISwipeGestureRecognizerDirection.Right: //画面の左半分にいれば右に移動する。 if(xConstraint.constant <= 0) { xConstraint.constant = xConstraint.constant + view.frame.size.width/2 - testLabel.frame.size.width/2 } default: //画面の右半分にいれば左に移動する。 if(xConstraint.constant >= 0) { xConstraint.constant = xConstraint.constant - view.frame.size.width/2 + testLabel.frame.size.width/2 } } //アニメーションさせる。 UIView.animateWithDuration(1.0, animations:{self.view.layoutIfNeeded()}, completion:nil) } } |
以下は実際のプレイ動画