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

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

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

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

Swift

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

Q&A

解決済

1回答

392閲覧

iOSフォトライブラリの写真をドラッグ操作時に、トリミング枠から出ないようにしたい

RyomaD

総合スコア34

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/09/23 10:00

編集2018/09/23 10:59

フォトライブラリの写真をドラッグ操作時に、トリミング枠から出ないようにしたいと考えております。
現状のドラッグ時は以下のような形になっており、
イメージ説明

「picker.allowsEditing = true」を設定した時のような挙動にしたいと考えております。
(ドラッグ操作した際に画像がトリミング枠から出たらふわっと戻るような仕様です。)

「picker.allowsEditing = true」を使えば済むような話ですが、
どうしてもデフォルトのトリミング枠の形状を変更できなので、自作中です。

コードは以下のようになっております。

swift

1 2 var image : UIImage! 3 var imageView : UIImageView! //トリミング対象画像を表示するためのUIImageView 4 var previousImages = [UIImage]() 5 var nextImages = [UIImage]() 6 var scaleZoomedInOut : CGFloat = 1.0 //拡大・縮小した時にはUIImageViewのサイズのみが変わるので、実際のUIImageのサイズとUIImageViewとの倍率の差を記録する 7 var previousScaleZoomedInOut = [CGFloat]() 8 var nextScaleZoomedInOut = [CGFloat]() 9 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 } 14 15 override func viewDidAppear(_ animated: Bool) { 16 super.viewWillAppear(true) 17 finishEditingButton.addTarget(self, action: #selector(finishEdittingAlert), for: .touchUpInside) 18 19 editPhotoView.layer.borderColor = UIColor.black.cgColor 20 editPhotoView.layer.borderWidth = 1 21 setUpPinchInOutAndDoubleTap() 22 23 //load image and show UIImageView 24 let appDelegate = UIApplication.shared.delegate as! AppDelegate 25 image = appDelegate.photoLibraryImage 26 previousScaleZoomedInOut.append(scaleZoomedInOut) 27 createImageView(sourceImage: image, on: editPhotoView) 28 mainStackView.bringSubview(toFront: headerView) 29 } 30 31 32 33 func createImageView(sourceImage: UIImage, on parentView: UIView){ 34 imageView = UIImageView(image: sourceImage) 35 // 画像の幅・高さの取得 36 let imageWidth = sourceImage.size.width 37 let imageHeight = sourceImage.size.height 38 let screenWidth = editPhotoView.frame.width 39 let screenHeight = editPhotoView.frame.height 40 41 if scaleZoomedInOut == 1.0{ 42 if imageHeight > screenHeight{ 43 scaleZoomedInOut = screenHeight/imageHeight 44 } 45 } 46 47 let rect:CGRect = CGRect(x:0, y:0, width:scaleZoomedInOut*imageWidth, height:scaleZoomedInOut*imageHeight) 48 imageView.frame = rect// ImageView frame をCGRectで作った矩形に合わせる 49 imageView.contentMode = .scaleAspectFill // Aspect Fill = 縦横の比率はそのままで短い辺を基準に全体を表示する 50 imageView.center = CGPoint(x:screenWidth/2, y:screenHeight/2) // 画像の中心をスクリーンの中心位置に設定 51 52 parentView.addSubview(imageView) 53 parentView.sendSubview(toBack: imageView) 54 } 55 56 //上下左右の移動は、ドラッグ操作できる。 57 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 58 59 // タッチイベントを取得. 60 let aTouch: UITouch = touches.first! 61 62 // 移動した先の座標を取得. 63 let location = aTouch.location(in: editPhotoView) 64 65 // 移動する前の座標を取得. 66 let prevLocation = aTouch.previousLocation(in: editPhotoView) 67 68 //移動した距離 69 let deltaX = location.x - prevLocation.x 70 let deltaY = location.y - prevLocation.y 71 72 // 移動した分の距離を座標にプラスする. 73 imageView.frame.origin.x += deltaX 74 imageView.frame.origin.y += deltaY 75 76 } 77 78@objc func pinchAction(gesture: UIPinchGestureRecognizer) { 79 80 if gesture.state == UIGestureRecognizerState.began { 81 // ピンチを開始したときの画像の中心点を保存しておく 82 pinchStartImageCenter = imageView.center 83 touchPoint1 = gesture.location(ofTouch: 0, in: self.view) 84 touchPoint2 = gesture.location(ofTouch: 1, in: self.view) 85 86 // 指の中間点を求めて保存しておく 87 // UIGestureRecognizerState.Changedで毎回求めた場合、ピンチ状態で片方の指だけ動かしたときに中心点がずれておかしな位置でズームされるため 88 pichCenter = CGPoint(x: (touchPoint1.x + touchPoint2.x) / 2, y: (touchPoint1.y + touchPoint2.y) / 2) 89 90 } else if gesture.state == UIGestureRecognizerState.changed { 91 // ピンチジェスチャー・変更中 92 var pinchScale : CGFloat// ピンチを開始してからの拡大率。差分ではない 93 if gesture.scale > 1 { 94 pinchScale = 1 + gesture.scale/100 95 }else{ 96 pinchScale = gesture.scale 97 } 98 if pinchScale*self.imageView.frame.width < editPhotoView.frame.width { 99 pinchScale = editPhotoView.frame.width/self.imageView.frame.width 100 } 101 scaleZoomedInOut *= pinchScale 102 103 // ピンチした位置を中心としてズーム(イン/アウト)するように、画像の中心位置をずらす 104 let newCenter = CGPoint(x: pinchStartImageCenter.x - ((pichCenter.x - pinchStartImageCenter.x) * pinchScale - (pichCenter.x - pinchStartImageCenter.x)),y: pinchStartImageCenter.y - ((pichCenter.y - pinchStartImageCenter.y) * pinchScale - (pichCenter.y - pinchStartImageCenter.y))) 105 self.imageView.frame.size = CGSize(width: pinchScale*self.imageView.frame.width, height: pinchScale*self.imageView.frame.height) 106 imageView.center = newCenter 107 } 108 } 109 110 //ダブルタップは、ダブルタップを行うとタップをしたところを中心にUIImageViewが2倍の大きさになる 111 @objc func doubleTapAction(gesture: UITapGestureRecognizer) { 112 113 if gesture.state == UIGestureRecognizerState.ended { 114 115 let doubleTapStartCenter = imageView.center 116 let doubleTapScale: CGFloat = 2.0 // ダブルタップでは現在のスケールの2倍にする 117 scaleZoomedInOut *= doubleTapScale 118 let tapPoint = gesture.location(in: self.view) 119 let newCenter = CGPoint(x: 120 doubleTapStartCenter.x - ((tapPoint.x - doubleTapStartCenter.x) * doubleTapScale - (tapPoint.x - doubleTapStartCenter.x)), 121 y: doubleTapStartCenter.y - ((tapPoint.y - doubleTapStartCenter.y) * doubleTapScale - (tapPoint.y - doubleTapStartCenter.y))) 122 123 // 拡大・縮小とタップ位置に合わせた中心点の移動 124 UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.curveEaseOut, animations: {() -> Void in 125 self.imageView.frame.size = CGSize(width: doubleTapScale*self.imageView.frame.width, height: doubleTapScale*self.imageView.frame.height) 126 self.imageView.center = newCenter 127 }, completion: nil) 128 } 129 }

ドラッグして画像を動かした際に移動した距離を割り出し、
トリミング対象画像を表示するためのUIImageViewのorigin.x(y)をインクリメントすることで
動作しております。

試したこと

swift

1if imageView.frame.origin.y < 0{ 2 imageView.frame.origin.y = 0 3 }else if imageView.frame.origin.y > 0{ 4 imageView.frame.origin.y = 0 5 }else if imageView.frame.origin.x > 0{ 6 imageView.frame.origin.x = 0 7 }

上記のやり方ではトリミング枠から出ないものの、ピンチインアウト時や、ズームインアウト時におかしな挙動になり想定の動きかたをしてくれませんでした。

画像の幅・高さを取得して、=> let imageWidth = sourceImage.size.width

「トリミング対象画像を表示するためのUIImageViewが、let imageWidth 以上になったらドラッグ移動させない」ようなやり方で試そうと思っています。

他に拡張性の高いやり方など、ご存知の方がいらっしゃればご教授頂けないでしょうか!!!!!
よろしくお願いします。

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

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

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

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

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

guest

回答1

0

自己解決

一応、ドラッグ移動時は余白が出ないようになっています。
ピンチインアウト時の挙動が理想の挙動とは異なるので引き続き改善してみます。

swift

1if imageView.frame.origin.y < 0{ 2 imageView.frame.origin.y = 0 3 }else if imageView.frame.origin.y > 0{ 4 imageView.frame.origin.y = 0 5 }else if imageView.frame.origin.x > 0{ 6 imageView.frame.origin.x = 0 7 }else if editPhotoView.frame.size.width > (imageView.frame.size.width + imageView.frame.origin.x){ 8 imageView.frame.origin.x += editPhotoView.frame.size.width - (imageView.frame.size.width + imageView.frame.origin.x) 9 }

投稿2018/09/23 16:16

RyomaD

総合スコア34

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問