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

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

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

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

解決済

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

mimamo
mimamo

総合スコア0

Swift

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

1回答

0評価

0クリップ

10閲覧

投稿2018/12/19 01:39

編集2022/01/12 10:58

前提・実現したいこと

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

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

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

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

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

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

該当のソースコード

Swift

import UIKit class ViewController2: UIViewController, UIGestureRecognizerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate { @IBOutlet var rotationRecognizer: UIRotationGestureRecognizer! @IBOutlet var pinchRecognizer: UIPinchGestureRecognizer! @IBOutlet weak var getphoto: UIImageView! override func viewDidLoad() { super.viewDidLoad() getphoto.image = firstImg //デリゲート先に自分を設定する。 rotationRecognizer.delegate = self pinchRecognizer.delegate = self //アフィン変換の初期値を設定する。 prevEndPinch = getphoto.transform prevEndRotate = getphoto.transform prevPinch = getphoto.transform prevRotate = getphoto.transform // タッチ操作を enable getphoto.isUserInteractionEnabled = true self.view?.addSubview(getphoto) ////////////////////////////////拡大・回転↓ //ドラッグ終了時のアフィン変換 var prevEndPinch:CGAffineTransform = CGAffineTransform() var prevEndRotate:CGAffineTransform = CGAffineTransform() //ドラッグ中の前回アフィン変換 var prevPinch:CGAffineTransform = CGAffineTransform() var prevRotate:CGAffineTransform = CGAffineTransform() @IBAction func pinchPhoto(_ sender: UIPinchGestureRecognizer) { print("pinch!") //前回ドラッグ終了時の拡大縮小を引き継いだアフィン変換を行う。 let nowPinch = prevEndPinch.scaledBy(x: sender.scale, y: sender.scale) //拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。 getphoto.transform = prevRotate.concatenating(nowPinch) //今回の拡大縮小のアフィン変換をクラス変数に保存する。 prevPinch = nowPinch if(sender.state == UIGestureRecognizerState.ended) { //ドラッグ終了時の拡大終了のアフィン変換をクラス変数に保存する。 prevEndPinch = nowPinch } } @IBAction func rotatePhoto(_ sender: UIRotationGestureRecognizer) { print("rotate!") //前回ドラッグ終了時の回転を引き継いだアフィン変換を行う。 let nowRotate = prevEndRotate.rotated(by: sender.rotation) //拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。 getphoto.transform = prevPinch.concatenating(nowRotate) //今回の回転のアフィン変換をクラス変数に保存する。 prevRotate = nowRotate if(sender.state == UIGestureRecognizerState.ended) { //ドラッグ終了時の回転のアフィン変換をクラス変数に保存する。 prevEndRotate = nowRotate } } ////////////////////////////////↑ ///////////////////////////////////////////画像の移動↓ //タッチしたビューの中心とタッチした場所の座標のズレを保持する変数 var gapX:CGFloat = 0.0 // x座標 var gapY:CGFloat = 0.0 // y座標 // タッチした位置で最初に見つかったところにあるビューを取得してしまおうという魂胆 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { // 最初にタッチした指のみ取得 if let touch = touches.first { print("touchbegin!") // タッチしたビューをviewプロパティで取得する if let touchedView = touch.view { // tag1のものを動かす if touchedView.tag == 1 { // タッチした場所とタッチしたビューの中心座標がどうずれているか? gapX = touch.location(in: view).x - touchedView.center.x gapY = touch.location(in: view).y - touchedView.center.y // 例えば、タッチしたビューの中心のxが50、タッチした場所のxが60→中心から10ずれ // この場合、指を100に持って行ったらビューの中心は90にしたい // ビューの中心90 = 持って行った場所100 - ずれ10 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) } } } } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { // touchesBeganと同じ処理だが、gapXとgapYはタッチ中で同じものを使い続ける // 最初にタッチした指のみ取得 if let touch = touches.first { // タッチしたビューをviewプロパティで取得する if let touchedView = touch.view { // tag1のものを動かす if touchedView.tag == 1 { // gapX,gapYの取得は行わない touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) } } } } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { // gapXとgapYの初期化 gapX = 0.0 gapY = 0.0 } override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { // touchesEndedと同じ処理 self.touchesEnded(touches, with: event) } ///////////////////////////////////////////↑ //リコグナイザーの同時検知を許可するメソッド func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }

###試したこと

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

Swift

///////////////////////////////////////////拡大縮小↓ var currentScale:CGFloat = 1.0 @objc func pinchAction(sender: UIPinchGestureRecognizer) { // imageViewを拡大縮小する // ピンチ中の拡大率は0.3〜2.5倍、指を離した時の拡大率は0.5〜2.0倍とする switch sender.state { case .began, .changed: // senderのscaleは、指を動かしていない状態が1.0となる // 現在の拡大率に、(scaleから1を引いたもの) / 10(補正率)を加算する currentScale = currentScale + (sender.scale - 1) / 10 // 拡大率が基準から外れる場合は、補正する if currentScale < 0.3 { currentScale = 0.3 } else if currentScale > 2.5 { currentScale = 2.5 } // 計算後の拡大率で、imageViewを拡大縮小する getphoto.transform = CGAffineTransform(scaleX: currentScale, y: currentScale) default: // ピンチ中と同様だが、拡大率の範囲が異なる if currentScale < 0.5 { currentScale = 0.5 } else if currentScale > 2.0 { currentScale = 2.0 } // 拡大率が基準から外れている場合、指を離したときにアニメーションで拡大率を補正する // 例えば指を離す前に拡大率が0.3だった場合、0.2秒かけて拡大率が0.5に変化する UIView.animate(withDuration: 0.2, animations: { self.getphoto.transform = CGAffineTransform(scaleX: self.currentScale, y: self.currentScale) }, completion: nil) } }

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

Swiftのversionは4.1.2
Xcodeのversionは9.4.1

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Swift

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