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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

1回答

2427閲覧

Swift UIImageViewの移動できる範囲を指定する

lyzmfeqpxs54

総合スコア237

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

1クリップ

投稿2018/11/22 03:28

いつもお世話になっております。
現在以下のようにUIViewのサイズを固定し、その上にUIImageを乗せることで、その範囲内で画像をピンチによって拡大、縮小、ドラッグできるようにしております。
現在のままですと移動範囲が自由なので、画面外に画像をドラッグできてしまい、その後戻せなくなってしまいます。画像の拡大後移動した際に、画像以外の部分が表示されないよう(SCrollViewに大きいサイズのものを入れた場合に動かせるような範囲)にするにはどのようにすればよいのでしょうか。

こういった仕様のカスタムビューについて紹介している記事でも構いませんのでご教示いただけますと幸いです。
よろしくお願いいたします。

Swift

1 2 var contentsImageView:UIView! 3 var pinchImageView:UIImageView! 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 // 画像のサイズを取得 8 let viewImge = UIImage(named: questionArray[imageViewNum]+".png") 9 let imageWidth = viewImge?.size.width 10 let imageHeight = viewImge?.size.height 11 // コンテンツの高さを算出 12 let heightQuestion = imageHeight!*widthQuestion/imageWidth! 13 contentsImageView.frame = CGRect(x: scrollBuffer + scWid * 0.1, 14 y: quesY, 15 width: widthQuestion, 16 height: heightQuestion) 17 contentsImageView.layer.borderWidth = 1 18 contentsImageView.layer.masksToBounds = true 19 questionScrollView.addSubview(contentsImageView) 20 21 // 枠と同じサイズImageViewを用意 22 pinchImageView = UIImageView() 23 pinchImageView.frame = CGRect(x: 0, 24 y: 0, 25 width: widthQuestion, 26 height: heightQuestion) 27 pinchImageView.image = viewImge 28 contentsImageView.addSubview(pinchImageView) 29 // imageViewにジェスチャーレコグナイザを設定する(ピンチ) 30 let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction(sender:))) 31 pinchImageView.isUserInteractionEnabled = true 32 pinchImageView.addGestureRecognizer(pinchGesture) 33 // imageViewにジェスチャーレコグナイザを設定する(ドラッグ) 34 let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panAction(gesture:))) 35 panGesture.minimumNumberOfTouches = 1 36 panGesture.maximumNumberOfTouches = 2 37 pinchImageView.addGestureRecognizer(panGesture) 38 } 39 40 // 画像の拡大率 41 var currentScale:CGFloat = 1.0 42 // 画像の拡大縮小時に呼ばれる 43 @objc func pinchAction(sender: UIPinchGestureRecognizer) { 44 // imageViewを拡大縮小する 45 // ピンチ中の拡大率は0.3〜2.5倍、指を離した時の拡大率は0.5〜2.0倍とする 46 switch sender.state { 47 case .began, .changed: 48 // senderのscaleは、指を動かしていない状態が1.0となる 49 // 現在の拡大率に、(scaleから1を引いたもの) / 10(補正率)を加算する 50 currentScale = currentScale + (sender.scale - 1) / 10 51 // 拡大率が基準から外れる場合は、補正する 52 if currentScale < 1.0 { 53 currentScale = 1.0 54 } else if currentScale > 3.0 { 55 currentScale = 3.0 56 } 57 // 計算後の拡大率で、imageViewを拡大縮小する 58 pinchImageView.transform = CGAffineTransform(scaleX: currentScale, y: currentScale) 59 default: 60 // ピンチ中と同様だが、拡大率の範囲が異なる 61 if currentScale < 1.0 { 62 currentScale = 1.0 63 } else if currentScale > 3.0 { 64 currentScale = 3.0 65 } 66 67 // 拡大率が基準から外れている場合、指を離したときにアニメーションで拡大率を補正する 68 // 例えば指を離す前に拡大率が0.3だった場合、0.2秒かけて拡大率が0.5に変化する 69 UIView.animate(withDuration: 0.2, animations: { 70 self.pinchImageView.transform = CGAffineTransform(scaleX: self.currentScale, y: self.currentScale) 71 }, completion: nil) 72 73 } 74 } 75 @objc func panAction(gesture: UIPanGestureRecognizer) { 76 77 // 現在のtransfromを保存 78 let transform = pinchImageView.transform 79 80 // imageViewのtransformを初期値に戻す 81 // これを入れないと、拡大時のドラッグの移動量が少なくなってしまう 82 pinchImageView.transform = CGAffineTransform.identity 83 84 // 画像をドラッグした量だけ動かす 85 let point: CGPoint = gesture.translation(in: pinchImageView) 86 let movedPoint = CGPoint(x: pinchImageView.center.x + point.x, 87 y: pinchImageView.center.y + point.y) 88 pinchImageView.center = movedPoint 89 90 // 保存しておいたtransformに戻す 91 pinchImageView.transform = transform 92 let CGPointZero = CGPoint(x:0, y:0) 93 // ドラッグで移動した距離をリセット 94 gesture.setTranslation(CGPointZero, in: pinchImageView) 95 96 } 97 98

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

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

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

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

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

guest

回答1

0

実現したいことをちゃんと理解していないかもしれませんが
UIScrollViewではダメそうですか?
UIScrollViewにはmaximumZoomScaleという便利なものがあります

例えば世にある拡大できるスライドイメージのほとんどはUIScrollViewを使っています

例 https://qiita.com/shift_option_k/items/eea52a662ae64258fb6f

投稿2018/11/22 09:47

kosanai

総合スコア471

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問