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

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

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

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

Q&A

解決済

1回答

431閲覧

画像をタッチすることで好きなように回転、拡大縮小、移動できるようにしたい

mimamo

総合スコア44

Swift

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

0グッド

0クリップ

投稿2018/12/19 01:39

編集2018/12/19 02:33

前提・実現したいこと

スタンプのように、画像を好きな位置に好きな角度、大きさで配置できるようにしたいです。

ご教授よろしくお願いいたします。

参考資料1…storyboard上でRotationGestureRecognizerとPinchGestureRecognizerを設置
参考資料2…storyboardをいじらない

発生している問題・エラーメッセージ

移動、回転はできるのですが、拡大縮小ができません。

Rotation,Pinch,touchを認識したらそれぞれprintするように指示しているのですが、touchとRotationの部分だけprintされ、pinchに関してはprintされませんでした。

該当のソースコード

Swift

1 2import UIKit 3 4 5class ViewController2: UIViewController, UIGestureRecognizerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate { 6 7@IBOutlet var rotationRecognizer: UIRotationGestureRecognizer! 8@IBOutlet var pinchRecognizer: UIPinchGestureRecognizer! 9@IBOutlet weak var getphoto: UIImageView! 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 getphoto.image = firstImg 15 16 //デリゲート先に自分を設定する。 17 rotationRecognizer.delegate = self 18 pinchRecognizer.delegate = self 19 20 //アフィン変換の初期値を設定する。 21 prevEndPinch = getphoto.transform 22 prevEndRotate = getphoto.transform 23 prevPinch = getphoto.transform 24 prevRotate = getphoto.transform 25 26 // タッチ操作を enable 27 getphoto.isUserInteractionEnabled = true 28 self.view?.addSubview(getphoto) 29} 30 31////////////////////////////////拡大・回転↓ 32 //ドラッグ終了時のアフィン変換 33 var prevEndPinch:CGAffineTransform = CGAffineTransform() 34 var prevEndRotate:CGAffineTransform = CGAffineTransform() 35 36 //ドラッグ中の前回アフィン変換 37 var prevPinch:CGAffineTransform = CGAffineTransform() 38 var prevRotate:CGAffineTransform = CGAffineTransform() 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 80///////////////////////////////////////////画像の移動↓ 81 82 83 //タッチしたビューの中心とタッチした場所の座標のズレを保持する変数 84 var gapX:CGFloat = 0.0 // x座標 85 var gapY:CGFloat = 0.0 // y座標 86 87 88 // タッチした位置で最初に見つかったところにあるビューを取得してしまおうという魂胆 89 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 90 // 最初にタッチした指のみ取得 91 if let touch = touches.first { 92 print("touchbegin!") 93 // タッチしたビューをviewプロパティで取得する 94 if let touchedView = touch.view { 95 // tag1のものを動かす 96 if touchedView.tag == 1 { 97 // タッチした場所とタッチしたビューの中心座標がどうずれているか? 98 gapX = touch.location(in: view).x - touchedView.center.x 99 gapY = touch.location(in: view).y - touchedView.center.y 100 // 例えば、タッチしたビューの中心のxが50、タッチした場所のxが60→中心から10ずれ 101 // この場合、指を100に持って行ったらビューの中心は90にしたい 102 // ビューの中心90 = 持って行った場所100 - ずれ10 103 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) 104 } 105 } 106 } 107 } 108 109 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 110 // touchesBeganと同じ処理だが、gapXとgapYはタッチ中で同じものを使い続ける 111 // 最初にタッチした指のみ取得 112 if let touch = touches.first { 113 // タッチしたビューをviewプロパティで取得する 114 if let touchedView = touch.view { 115 // tag1のものを動かす 116 if touchedView.tag == 1 { 117 // gapX,gapYの取得は行わない 118 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) 119 } 120 } 121 } 122 } 123 124 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 125 // gapXとgapYの初期化 126 gapX = 0.0 127 gapY = 0.0 128 } 129 130 override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { 131 // touchesEndedと同じ処理 132 self.touchesEnded(touches, with: event) 133 } 134///////////////////////////////////////////↑ 135 136//リコグナイザーの同時検知を許可するメソッド 137 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 138 return true 139 } 140 141 142override func didReceiveMemoryWarning() { 143 super.didReceiveMemoryWarning() 144 // Dispose of any resources that can be recreated. 145} 146 147}

###試したこと

参考資料2を元に移動と拡大縮小まではできたのですが、回転はどのようにコーディングすればよいのかわからずコーディングを進めることが出来ませんでした。

Swift

1 2///////////////////////////////////////////拡大縮小↓ 3 4 var currentScale:CGFloat = 1.0 5 6@objc func pinchAction(sender: UIPinchGestureRecognizer) { 7 // imageViewを拡大縮小する 8 // ピンチ中の拡大率は0.3〜2.5倍、指を離した時の拡大率は0.5〜2.0倍とする 9 switch sender.state { 10 case .began, .changed: 11 // senderのscaleは、指を動かしていない状態が1.0となる 12 // 現在の拡大率に、(scaleから1を引いたもの) / 10(補正率)を加算する 13 currentScale = currentScale + (sender.scale - 1) / 10 14 // 拡大率が基準から外れる場合は、補正する 15 if currentScale < 0.3 { 16 currentScale = 0.3 17 } else if currentScale > 2.5 { 18 currentScale = 2.5 19 } 20 // 計算後の拡大率で、imageViewを拡大縮小する 21 getphoto.transform = CGAffineTransform(scaleX: currentScale, y: currentScale) 22 default: 23 // ピンチ中と同様だが、拡大率の範囲が異なる 24 if currentScale < 0.5 { 25 currentScale = 0.5 26 } else if currentScale > 2.0 { 27 currentScale = 2.0 28 } 29 30 // 拡大率が基準から外れている場合、指を離したときにアニメーションで拡大率を補正する 31 // 例えば指を離す前に拡大率が0.3だった場合、0.2秒かけて拡大率が0.5に変化する 32 UIView.animate(withDuration: 0.2, animations: { 33 self.getphoto.transform = CGAffineTransform(scaleX: self.currentScale, y: self.currentScale) 34 }, completion: nil) 35 36 } 37 } 38

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

Swiftのversionは4.1.2
Xcodeのversionは9.4.1

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

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

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

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

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

guest

回答1

0

自己解決

バグだったのかわかりませんが、拡大縮小も含め移動、回転ができるようになりました。

投稿2018/12/19 02:36

mimamo

総合スコア44

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問