前提・実現したいこと
今、touchやRotation、PinchすることでUIImageViewを移動、回転、拡大縮小できるようにしています。
次に、移動の制限をしていきたいと思っているのですが、どのようにすればうまくいくのかわかりません。
storyboardに設定したUIview上でだけ可能にしたいと思っています。
下の画像のように、UIImageView(getphoto)が全て画面内に収まる範囲で移動を可能にしたいです。
下のようにUIImageViewが一部もしくは全て消えてしまうのを避けたいです。
サンプルコードやご教授、よろしくお願いいたします。
該当のソースコード
Swift
1 2class ViewController2: UIViewController, UIGestureRecognizerDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate { 3 4 @IBOutlet var rotationRecognizer: UIRotationGestureRecognizer! 5 6 @IBOutlet var pinchRecognizer: UIPinchGestureRecognizer! 7 8//移動、拡大縮小、回転させたいUIImageView 9 @IBOutlet weak var getphoto: UIImageView! 10 let firstImg: UIImage = UIImage(named: "IMG_6632.JPG")! 11 12 override func viewDidLoad() { 13 super.viewDidLoad() 14 15 //デリゲート先に自分を設定する。 16 rotationRecognizer.delegate = self 17 pinchRecognizer.delegate = self 18 19 //アフィン変換の初期値を設定する。 20 prevEndPinch = getphoto.transform 21 prevEndRotate = getphoto.transform 22 prevPinch = getphoto.transform 23 prevRotate = getphoto.transform 24 25 26 // タッチ操作を enable 27 getphoto.isUserInteractionEnabled = true 28 self.view?.addSubview(getphoto) 29 30 getphoto.image = firstImg 31} 32 33//////////////////////////////////////拡大縮小・回転↓ 34 35//ドラッグ終了時のアフィン変換 36 var prevEndPinch:CGAffineTransform = CGAffineTransform() 37 var prevEndRotate:CGAffineTransform = CGAffineTransform() 38 39 //ドラッグ中の前回アフィン変換 40 var prevPinch:CGAffineTransform = CGAffineTransform() 41 var prevRotate:CGAffineTransform = CGAffineTransform() 42 43 44 @IBAction func pinchPhoto(_ sender: UIPinchGestureRecognizer) { 45 print("pinch!") 46 //前回ドラッグ終了時の拡大縮小を引き継いだアフィン変換を行う。 47 let nowPinch = 48 prevEndPinch.scaledBy(x: sender.scale, y: sender.scale) 49 50 //拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。 51 getphoto.transform = prevRotate.concatenating(nowPinch) 52 53 //今回の拡大縮小のアフィン変換をクラス変数に保存する。 54 prevPinch = nowPinch 55 56 if(sender.state == UIGestureRecognizerState.ended) { 57 //ドラッグ終了時の拡大終了のアフィン変換をクラス変数に保存する。 58 prevEndPinch = nowPinch 59 } 60 61 } 62 63 @IBAction func rotatePhoto(_ sender: UIRotationGestureRecognizer){ 64 65 print("rotate!") 66 //前回ドラッグ終了時の回転を引き継いだアフィン変換を行う。 67 let nowRotate = prevEndRotate.rotated(by: sender.rotation) 68 69 //拡大縮小と回転のアフィン変換を合わせたものをラベルに登録する。 70 getphoto.transform = prevPinch.concatenating(nowRotate) 71 72 //今回の回転のアフィン変換をクラス変数に保存する。 73 prevRotate = nowRotate 74 75 if(sender.state == UIGestureRecognizerState.ended) { 76 //ドラッグ終了時の回転のアフィン変換をクラス変数に保存する。 77 prevEndRotate = nowRotate 78 } 79 80 } 81 82//////////////////////////////////////画像の移動↓ 83 84 //タッチしたビューの中心とタッチした場所の座標のズレを保持する変数 85 var gapX:CGFloat = 0.0 // x座標 86 var gapY:CGFloat = 0.0 // y座標 87 88 //UIImageのサイズ取得 89 let photoWidth = self.getphoto.image?.size.width 90 let photoHeight = self.getphoto.image?.size.height 91 92 93 // タッチした位置で最初に見つかったところにあるビューを取得してしまおうという魂胆 94 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 95 // 最初にタッチした指のみ取得 96 if let touch = touches.first { 97 print("touchbegin!") 98 // タッチしたビューをviewプロパティで取得する 99 if let touchedView = touch.view { 100 // tag1のものを動かす 101 if touchedView.tag == 1 { 102 // タッチした場所とタッチしたビューの中心座標がどうずれているか? 103 gapX = touch.location(in: view).x - touchedView.center.x 104 gapY = touch.location(in: view).y - touchedView.center.y 105 // 例えば、タッチしたビューの中心のxが50、タッチした場所のxが60→中心から10ずれ 106 // この場合、指を100に持って行ったらビューの中心は90にしたい 107 // ビューの中心90 = 持って行った場所100 - ずれ10 108 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) 109 } 110 } 111 } 112 } 113 114 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 115 // touchesBeganと同じ処理だが、gapXとgapYはタッチ中で同じものを使い続ける 116 // 最初にタッチした指のみ取得 117 if let touch = touches.first { 118 // タッチしたビューをviewプロパティで取得する 119 if let touchedView = touch.view { 120 // tag1のものを動かす 121 if touchedView.tag == 1 { 122 // gapX,gapYの取得は行わない 123 touchedView.center = CGPoint(x: touch.location(in: view).x - gapX, y: touch.location(in: view).y - gapY) 124 } 125 } 126 } 127 } 128 129 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 130 // gapXとgapYの初期化 131 gapX = 0.0 132 gapY = 0.0 133 } 134 135 override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { 136 // touchesEndedと同じ処理 137 self.touchesEnded(touches, with: event) 138 } 139 140 141 //リコグナイザーの同時検知を許可するメソッド 142 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 143 return true 144 } 145 146override func didReceiveMemoryWarning() { 147 super.didReceiveMemoryWarning() 148 // Dispose of any resources that can be recreated. 149} 150 151} 152
試したこと
UIImageView(getphoto)の大きさと中心座標と移動可能にしたい範囲を組み合わせてコードを組めばいいのかなと思ったのですが、実際にどのようにコーディングすればいいのかわかりません。
###エラー
UIImageViewの大きさを知りたくてコーディングしてみたのですがエラーが出てしまいました。
Swift
1//UIImageView(getphoto)のサイズ取得 2 let photoWidth = self.getphoto.image?.size.width 3 let photoHeight = self.getphoto.image?.size.height
エラー
Value of type '(ViewController2) -> () -> (ViewController2)' has no member 'getphoto'
補足情報(FW/ツールのバージョンなど)
Swiftのversionは4.1.2
Xcodeのversionは9.4.1
回答1件
あなたの回答
tips
プレビュー