Recognizerの使い方。2つの指で部品を回転させる。Recognizerの使い方。2つの指で部品を回転させる。Recognizer(以下、ローテーションリコグナイザー)について説明する。ローテーションリコグナイザーとは、部品をタッチしている2つの指の座標を結ぶ直線が回転したことを検知する部品である。前回記事のピンチリコグナイザーと使い方が似ているが、拡大縮小に比べると回転の使用頻度は多く無い。いうことは、新しいアイディアがそこに埋まっているかも知れない。⇒「ピンチリコグナイザーとは」ローテーションリコグナイザーを使ってみる実際にローテーションリコグナイザーを使ってみよう。デバイス画面にラベルを配置する(下図赤矢印)。黄枠のアトリビュートインスペクタボタンを押して設定画面を表示する。Enabledにチェックを入れる。紫枠のアシスタントエディタボタンを押してViewController.swfitを開く。Ctrlキーを押しながらラベルをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる(黄緑矢印)。Connectionに「Outlet」、Nameに「testLabel」を入力しConnectボタンを押す。これでラベルをソースコードから操作できるようになった。ローテーションリコグナイザーをラベルに配置する(下図赤矢印)。Ctrlキーを押しながら黄緑枠のローテーションリコグナイザーをソースコードまで運んで吹き出しの設定画面を表示させる(青矢印)。Connectionに「Action」、Nameに「rotateLabel」、Typeに「UIRotationGestureRecognizer」を設定し、Connectボタンを押す。これで2つの指が回転したときのイベントをソースコードで受けれるようになった。ViewController.swiftを以下のコードに変更する。ピンチリコグナイザーと同じように「回転時の呼び出しメソッド」が指を回すたびに呼び出される。前回ドラッグ終了時の回転をクラス変数に保存し、ドラッグ中はこの回転を引き継いだアフィン変換を行っている。これにより、回転位置が元に戻ることなく回転を再開することができるということだ。//前回ドラッグ終了時の回転をクラス変数に保存する。//前回ドラッグ終了時の回転を引き継いでアフィン変換を行う。{//前回ドラッグ終了時の回転をクラス変数に保存する。testLabel.transform}//前回ドラッグ終了時の回転を引き継いでアフィン変換を行う。sender.rotation)}}以下は実際のプレイ動画。ちなみにシミュレーターで2本の指を使うにはOptionキーを押しながら操作する。拡大縮小と回転を同時に行うピンチリコグナイザーとローテーションリコグナイザーを使ってみて思うことといえば「拡大縮小と回転を同時に行いたい」である。同時に行うためのデリゲートが用意されているので使ってみよう。以降の手順は上記手順の続きである。ピンチリコグナイザーをラベルに配置する(下図赤矢印)。黄緑枠のアシスタントエディタボタンを押してViewController.swiftを開く。Ctrlキーを押しながら紫枠のピンチリコグナイザーをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。Connectionに「Action」、Nameに「pinchLabel」、Typeに「UIPinchGestureRecognizer」を入力してConnectボタンを押す。これで、ピンチイン、ピンチアウトのイベントをソースコードで受けれるようになった。一度、Ctrlキーを押しながら紫枠のピンチリコグナイザーをドラッグ&ドロップでソースコードまで運んで吹き出しの設定画面を表示させる。Connectionに「Outlet」、Nameに「pinchRecognizer」を入力してConnectボタンを押す。水色枠のローテーションリコグナイザーも同様にして吹き出しの設定画面を表示させ、Connectionに「Outlet」、Nameに「rotationRecognizer」を入力しConnectボタンを押す。これでピンチリコグナイザーとローテーションリコグナイザーをソースコードから操作できるようになった。ViewController.swiftを以下のコードに変更する。2つのリコグナイザーが同じタイミングで動いたときにデリゲートメソッドの「リコグナイザーの同時検知を許可するメソッド」が呼び出されるのでtrueを返して同時検知を許可している。//デリゲート先に自分を設定する。//アフィン変換の初期値を設定する。//前回ドラッグ終了時の拡大縮小を引き継いだアフィン変換を行う。//拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。//今回の拡大縮小のアフィン変換をクラス変数に保存する。//ドラッグ終了時の拡大終了のアフィン変換をクラス変数に保存する。//前回ドラッグ終了時の回転を引き継いだアフィン変換を行う。//拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。//今回の回転のアフィン変換をクラス変数に保存する。//ドラッグ終了時の回転のアフィン変換をクラス変数に保存する。{super.viewDidLoad()//デリゲート先に自分を設定する。self//アフィン変換の初期値を設定する。{//前回ドラッグ終了時の拡大縮小を引き継いだアフィン変換を行う。sender.scale)//拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。nowPinch)//今回の拡大縮小のアフィン変換をクラス変数に保存する。{//ドラッグ終了時の拡大終了のアフィン変換をクラス変数に保存する。{//前回ドラッグ終了時の回転を引き継いだアフィン変換を行う。sender.rotation)//拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。nowRotate)//今回の回転のアフィン変換をクラス変数に保存する。{//ドラッグ終了時の回転のアフィン変換をクラス変数に保存する。true}}2つの指の拡大縮小操作が行われたときは「ピンチ時の呼び出しメソッド」が呼び出され、2つの指の回転操作が行われたときは「回転時の呼び出しメソッド」が呼び出される。どちらのメソッドでも拡大縮小と回転の両方のアフィン変換を行う必要があるのが注意点である。そのため、「ドラッグ終了時のアフィン変換」と「ドラッグ中のアフィン変換」をクラス変数に持たせている。ややこしくなってきたので、「ドラッグ終了時のアフィン変換」が必要な理由について回転の具体例を用いて説明する。部品がどれだけ回転したかは、「回転時の呼び出しメソッド」の引数から知ることができ、その角度は基準点からの角度になる。指を瞬時に11度回転させて1回目のメソッド呼び出しで回転角度11度が通知されたとする。そのまま指を画面から離さずに10度回転させて2回目のメソッド呼び出しが行われたときは21度(=11度+10度)が通知される。指を12度回転させて3回目のメソッド呼び出しでは33度(=11度+10度+12度)が通知される。ドラッグ中のメソッド呼び出しは前回メソッド呼び出し時からの回転角度が通知されるのではなく、部品の初期状態からの回転角度が通知される。そのため、一度画面から指を離したあとに再回転をさせるときは前回の回転を含めてアフィン変換をする必要がある。ドラッグ中の回転も含めて前回呼び出し時の回転角を引き継がせると、下図のように回転角が被って通常より大きな回転になってしまう。そのため、「ドラッグ終了時のアフィン変換」をクラス変数に保存しておき、引き継がせる回転角度を固定させるわけである。「回転時の呼び出しメソッド」の中で行う拡大縮小のアフィン変換は、ドラッグ中に変化している部品のサイズを反映するために直近の拡大縮小のアフィン変換が必要である。そのため、「ドラッグ中のアフィン変換」をクラス変数に保存し、他のメソッドで利用でるようにしている。回転させる部品の中の部品も一緒に回転し、機能してくれるのが嬉しい。ドラッグでコンテナビューを出し入れする。Recognizerの使い方。部品の長押しを検知する。Recognizerの使い方。2つの指で部品を拡大縮小する。Recognizerの使い方。画面端のドラッグを検知する。Recognizerの使い方。ドラッグ&ドロップを検知する。コメントをキャンセルメールアドレスが公開されることはありません。