質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

839閲覧

Swift4 ある画像を、タッチすることにより移動・拡大縮小・回転できるようにしたいのですが、回転についてのコードがわかりません。

mimamo

総合スコア44

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1グッド

1クリップ

投稿2018/12/16 03:07

編集2018/12/17 14:18

前提・実現したいこと

ある画像を、タッチすることで拡大縮小、移動、回転ができるようにしたいです。
今移動と拡大縮小はできているのですが、回転に関するコードがわからずどのようにすればいいのか困っています。
アドバイスやサンプルコードのご教授、よろしくお願いします。

参考資料1
参考資料2

該当のソースコード

Swift

1import UIKit 2 3 4class ViewController2: UIViewController, UIGestureRecognizerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate { 5 6 // 画像の拡大率 7 var currentScale:CGFloat = 1.0 8 9 let firstImg: UIImage = UIImage(named: "IMG_6632.JPG")! 10 @IBOutlet weak var getphoto: UIImageView! 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 getphoto.image = firstImg 15 16 // タッチ操作を enable 17 getphoto.isUserInteractionEnabled = true 18 self.view?.addSubview(getphoto) 19 20 // imageViewにジェスチャーレコグナイザを設定する(ピンチ) 拡大縮小 21 let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction(sender:))) 22 getphoto.addGestureRecognizer(pinchGesture) 23 24///////////////////////////////////////////画像の移動↓ 25 26 // タッチしたビューの中心とタッチした場所の座標のズレを保持する変数 27 var gapX:CGFloat = 0.0 // x座標 28 var gapY:CGFloat = 0.0 // y座標 29 30 31 32 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 33 // 最初にタッチした指のみ取得 34 if let touch = touches.first { 35 // タッチしたビューをviewプロパティで取得する 36 if let touchedView = touch.view { 37 // tag1のものを動かす 38 if touchedView.tag == 1 { 39 // タッチした場所とタッチしたビューの中心座標がどうずれているか? 40 gapX = touch.location(in: view).x - touchedView.center.x 41 gapY = touch.location(in: view).y - touchedView.center.y 42 // 例えば、タッチしたビューの中心のxが50、タッチした場所のxが60→中心から10ずれ 43 // この場合、指を100に持って行ったらビューの中心は90にしたい 44 // ビューの中心90 = 持って行った場所100 - ずれ10 45 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) 46 } 47 } 48 } 49 } 50 51 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 52 // touchesBeganと同じ処理だが、gapXとgapYはタッチ中で同じものを使い続ける 53 // 最初にタッチした指のみ取得 54 if let touch = touches.first { 55 // タッチしたビューをviewプロパティで取得する 56 if let touchedView = touch.view { 57 // tag1のものを動かす 58 if touchedView.tag == 1 { 59 // gapX,gapYの取得は行わない 60 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) 61 } 62 } 63 } 64 } 65 66 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 67 // gapXとgapYの初期化 68 gapX = 0.0 69 gapY = 0.0 70 } 71 72 override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { 73 // touchesEndedと同じ処理 74 self.touchesEnded(touches, with: event) 75 } 76 ///////////////////////////////////////////拡大縮小↓ 77 78 79 @objc func pinchAction(sender: UIPinchGestureRecognizer) { 80 // imageViewを拡大縮小する 81 // ピンチ中の拡大率は0.3〜2.5倍、指を離した時の拡大率は0.5〜2.0倍とする 82 switch sender.state { 83 case .began, .changed: 84 // senderのscaleは、指を動かしていない状態が1.0となる 85 // 現在の拡大率に、(scaleから1を引いたもの) / 10(補正率)を加算する 86 currentScale = currentScale + (sender.scale - 1) / 10 87 // 拡大率が基準から外れる場合は、補正する 88 if currentScale < 0.3 { 89 currentScale = 0.3 90 } else if currentScale > 2.5 { 91 currentScale = 2.5 92 } 93 // 計算後の拡大率で、imageViewを拡大縮小する 94 getphoto.transform = CGAffineTransform(scaleX: currentScale, y: currentScale) 95 default: 96 // ピンチ中と同様だが、拡大率の範囲が異なる 97 if currentScale < 0.5 { 98 currentScale = 0.5 99 } else if currentScale > 2.0 { 100 currentScale = 2.0 101 } 102 103 // 拡大率が基準から外れている場合、指を離したときにアニメーションで拡大率を補正する 104 // 例えば指を離す前に拡大率が0.3だった場合、0.2秒かけて拡大率が0.5に変化する 105 UIView.animate(withDuration: 0.2, animations: { 106 self.getphoto.transform = CGAffineTransform(scaleX: self.currentScale, y: self.currentScale) 107 }, completion: nil) 108 109 } 110 } 111 112//////////////////////////////////////////////////↑ 113 114override func didReceiveMemoryWarning() { 115 super.didReceiveMemoryWarning() 116 // Dispose of any resources that can be recreated. 117} 118 119} 120

##更新情報

回答者さまから頂いた資料を参考に拡大縮小・回転できるようにコーディングし、重要そうな部分を抜粋したものが下記になります。

<<エラー発生>>
実行自体はできるのですが、pinchやRotationを受け取っていないらしく画像は変化せずprintもされませんでした。

Swift

1import UIKit 2 3 4class ViewController2: UIViewController, UIGestureRecognizerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate { 5 6 @IBOutlet var rotationRecognizer: UIRotationGestureRecognizer! 7 8 @IBOutlet var pinchRecognizer: UIPinchGestureRecognizer! 9 10 @IBOutlet weak var getphoto: UIImageView! 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 //デリゲート先に自分を設定する。 15 rotationRecognizer.delegate = self 16 pinchRecognizer.delegate = self 17 18 //アフィン変換の初期値を設定する。 19 prevEndPinch = getphoto.transform 20 prevEndRotate = getphoto.transform 21 prevPinch = getphoto.transform 22 prevRotate = getphoto.transform 23 24// タッチ操作を enable 25 getphoto.isUserInteractionEnabled = true 26 self.view?.addSubview(getphoto) 27 28 getimage.image = UIImage(named:"binsen1.jpg")! 29} 30 31//ドラッグ終了時のアフィン変換 32 var prevEndPinch:CGAffineTransform = CGAffineTransform() 33 var prevEndRotate:CGAffineTransform = CGAffineTransform() 34 35 //ドラッグ中の前回アフィン変換 36 var prevPinch:CGAffineTransform = CGAffineTransform() 37 var prevRotate:CGAffineTransform = CGAffineTransform() 38 39 40 @IBAction func pinchPhoto(_ sender: UIPinchGestureRecognizer) { 41 print("pinch!") 42 //前回ドラッグ終了時の拡大縮小を引き継いだアフィン変換を行う。 43 let nowPinch = 44 prevEndPinch.scaledBy(x: sender.scale, y: sender.scale) 45 46 //拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。 47 getphoto.transform = prevRotate.concatenating(nowPinch) 48 49 //今回の拡大縮小のアフィン変換をクラス変数に保存する。 50 prevPinch = nowPinch 51 52 if(sender.state == UIGestureRecognizerState.ended) { 53 //ドラッグ終了時の拡大終了のアフィン変換をクラス変数に保存する。 54 prevEndPinch = nowPinch 55 } 56 57 } 58 59 60 61 @IBAction func rotatePhoto(_ sender: UIRotationGestureRecognizer) { 62 print("rotate!") 63 //前回ドラッグ終了時の回転を引き継いだアフィン変換を行う。 64 let nowRotate = prevEndRotate.rotated(by: sender.rotation) 65 66 //拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。 67 getphoto.transform = prevPinch.concatenating(nowRotate) 68 69 //今回の回転のアフィン変換をクラス変数に保存する。 70 prevRotate = nowRotate 71 72 if(sender.state == UIGestureRecognizerState.ended) { 73 //ドラッグ終了時の回転のアフィン変換をクラス変数に保存する。 74 prevEndRotate = nowRotate 75 } 76 } 77 78 //リコグナイザーの同時検知を許可するメソッド 79 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 80 return true 81 } 82 83 84override func didReceiveMemoryWarning() { 85 super.didReceiveMemoryWarning() 86 // Dispose of any resources that can be recreated. 87} 88 89} 90 91

補足情報(FW/ツールのバージョンなど)

Swiftのversionは4.1.2
Xcodeのversionは9.4.1

DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

サンプルコードは作成しておりませんが、
下記のサイトを参考に行えばできると思います。

https://i-app-tec.com/ios/cgaffinetransform.html

ちょっと時間があったので、サンプル作ってみました。

swift

1 2import UIKit 3 4class SampleViewController: UIViewController { 5 @IBOutlet var imageView:UIImageView! 6 7 override func viewDidLoad() { 8 super.viewDidLoad() 9 10 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SampleViewController.imageTapped)) 11 self.imageView.addGestureRecognizer(tapGesture) 12 } 13 14 func rotateImage(degree: Int, imageview: UIImageView){ 15 let angle = CGFloat(degree) * CGFloat.pi / 180 16 let transRotate = CGAffineTransform(rotationAngle: CGFloat(angle)); 17 imageview.transform = transRotate 18 19 print("Rotate: (angle)") 20 } 21 22 @objc func imageTapped() { 23 self.rotateImage(degree:90, imageview: self.imageView) 24 } 25}

これで大丈夫だと思います。
試してみください。

ちなみにtouchesBeganやtouchesMovedに
imageTappedの中身を書いても同じ動きすると思います。

投稿2018/12/16 16:44

編集2018/12/16 23:55
hameji001

総合スコア639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mimamo

2018/12/17 02:46

ご回答、またサンプルコードまで作っていただきありがとうございます! 私の質問が雑で申し訳ありません。 やりたい回転というのは、RotationRecognizerGestureを使って画像を2本指で回転させることで、自由に画像の傾きを変えれるようなものです。(完成させたいものとしては、スタンプを好きな場所に好きな大きさ・傾きで貼るようなイメージです。) 頂いたサンプルコードでは、無事に右に90度回転させることができました。
mimamo

2018/12/17 13:59

参考資料ありがとうございます。 はい、このようなことをできたらと思っております。 コーディングしてみたのですが、rotationもpinchの動作も受け取っていないようでした。 質問の方にコーディングした中身を追加しましたので、見て頂けると幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問