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

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

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

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

Swift

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

Q&A

1回答

1465閲覧

swiftで重なっている(または任意の座標にある)Viewを取得したい

ponponpoo

総合スコア1

Xcode

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

Swift

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

0グッド

0クリップ

投稿2020/09/19 17:37

編集2020/09/20 03:33

前提・実現したいこと

生成された1組のView1とView2を同時にpangestureで移動させたいです.

swift

1let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.moveView)) 2panGesture.delegate = self 3view1.addGestureRecognizer(panGesture) 4view1.isUserInteractionEnabled = true 5 6self.parent?.view.addSubview(view1) 7self.parent?.view.addSubview(view2)

のように,同じサイズ,座標のViewが親Viewにあります.

この動作は複数回繰り返されているので,親Viewにはこの動作によって
生成されたViewがいくつかあります.

そのため,

①gestureを検知したらview1に重なっているviewを取得
または,View1の座標からView2を取得(完全に重なっているものだけ)

②View1の座標変化とともにView2の座標も変える

を行いたいです.

よろしくおねがいします.

理想のコード

swift

1 @objc func moveView(sender: UIPanGestureRecognizer) { 2 //ここのsenderはView1 3 4 let location: CGPoint = sender.translation(in: parent!.view) 5 6 //view1と重なっているView2を取得したい 7 let view2 = ????? 8 9 view2.center.x += location.x 10 view2.center.y += location.y 11 12 sender.view?.center.x += location.x 13 sender.view?.center.y += location.y 14 15 16 sender.setTranslation(CGPoint.zero, in: self.view) 17 18 }

追記

親Viewの中にcontainerViewがあり,その中のImageViewを長押しすると
view1 view2が同じサイズ,位置,つまり,完全に重なった状態で親Viewに追加されます.
長押しは何回でも出来るのでview1とview2の1組は何個も親Viewに存在します.
イメージ図はこんな感じです ↓
![イメージ説明

このような感じで,
一回親に貼り付けられたview1とView2を一緒に動かしたいです.

ContainerViewのViewControllerは親Viewと異なります.
ContainerViewで,長押しを感知し,View1とView2を生成しています.
以下が該当コードです.

ContainerVC内で

swift

1 override func viewDidLoad() { 2 super.viewDidLoad() 3 //長押しをセット 4 let longPressGesture = 5 UILongPressGestureRecognizer(target: self, 6 action: #selector(self.longPress(_:))) 7 longPressGesture.delegate = self 8 self.imageView.addGestureRecognizer(longPressGesture) 9 } 10 11 //長押しされたら 12 @objc func longPress(_ sender: UILongPressGestureRecognizer){ 13 if sender.state == .began { 14 //View1 座標はランダム 15 view1 = UIImageView(frame: CGRect(x: x,y: y, width: 168, height: 90)) 16 let panGesture2 = UIPanGestureRecognizer(target: self, action: #selector(self.moveView)) 17 panGesture2.delegate = self 18 view1.addGestureRecognizer(panGesture2) 19 20 view1.isUserInteractionEnabled = true 21 22 //View2 Viewに重なるように表示 23 view2 = UIImageView(frame: CGRect(x: x,y: y, width: 168, height: 90)) 24 25 //Viewを追加 26 self.parent?.view.addSubview(view1) 27 self.parent?.view.addSubview(view2) 28 } 29 } 30 }

moveView()については上記の通りです.

pangestureをView1,2両方につけてもView2しか反応しない(VIew2が上にあるから?)ので
View1が動かされたときに対になっているView2を取得して
一緒に動かせばいいと考えたのですが,座標からViewを取得する方法がわからず・・・.

座標からというのは,
View1の中心がX,Yなので,中心が同じ他のVIewをview2にするような
イメージです.

ご教授お願いします.

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

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

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

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

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

TsukubaDepot

2020/09/19 20:55

> 生成された1組のView1とView2を同時にpangestureで移動させたいです. 条件がよく理解できないのですが、view1, view2 はどのように生成されるのでしょうか。 > この動作は複数回繰り返されているので,親Viewにはこの動作によって生成されたViewがいくつかあります. ここのあたりも実際にどのようにされているのか、ご説明だけではよく把握できません。 理想のコード以外に、全体的なコード(単独で動く最低限のコード)もご提示いただくことは可能でしょうか。
ponponpoo

2020/09/20 03:35

ご指摘ありがとうございます. 拙いですが追記にて修正しました. 初心者なので,これで足りているのかわかりませんので 足りてませんでしたらお手数ですがまたお知らせください. ご教授よろしくおねがいします.
guest

回答1

0

要件をよく把握しきれているわけではありませんが、こういうことでしょうか。

イメージ説明

要点としては、

Swift

1 //Viewを追加 2 self.parent?.view.addSubview(view1) 3 self.parent?.view.addSubview(view2)

と、2つのViewを別々に追加していたのを、階層づけて

Swift

1 //Viewを追加 2 view1.addSubview(view2) 3 self.parent?.view.addSubview(view1)

とした点です。

ContainerView 内の View Controller は次のような感じです。

Swift

1import UIKit 2 3class ContainerViewController: UIViewController { 4 @IBOutlet weak var imageView: UIImageView! 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 //長押しをセット 9 imageView.image = UIImage(systemName: "calendar.circle.fill") 10 let longPressGesture = 11 UILongPressGestureRecognizer(target: self, 12 action: #selector(self.longPress(_:))) 13 imageView.addGestureRecognizer(longPressGesture) 14 imageView.isUserInteractionEnabled = true 15 } 16 17 //長押しされたら 18 @objc func longPress(_ sender: UILongPressGestureRecognizer){ 19 if sender.state == .began { 20 if let parentViewController = parent as? ViewController { 21 let parentWidth = parentViewController.view.frame.width 22 let height = view.frame.height + 48 23 let imageWidth = parentWidth / 4 24 25 let x = imageWidth * CGFloat(Int.random(in: 0...3)) 26 let y = height + imageWidth * CGFloat(Int.random(in: 0...3)) 27 28 let baseImageView = UIImageView(frame: CGRect(x: x, y: y, width: parentWidth / 4, height: parentWidth / 4)) 29 let upperImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: parentWidth / 4, height: parentWidth / 4)) 30 31 baseImageView.image = UIImage() 32 baseImageView.backgroundColor = .orange 33 34 upperImageView.image = UIImage(systemName: "calendar.circle.fill") 35 36 37 let panGesture = UIPanGestureRecognizer(target: self, action: #selector(moveView(sender:))) 38 39 baseImageView.addGestureRecognizer(panGesture) 40 baseImageView.isUserInteractionEnabled = true 41 42 // View2 を View1 に addSubView する 43 baseImageView.addSubview(upperImageView) 44 parentViewController.view.addSubview(baseImageView) 45 } 46 } 47 } 48 49 @objc func moveView(sender: UIPanGestureRecognizer) { 50 if let parentViewController = parent as? ViewController, let baseImageView = sender.view as? UIImageView { 51 let location = sender.translation(in: parentViewController.view) 52 53 baseImageView.center.x += location.x 54 baseImageView.center.y += location.y 55 56 // 移動量をリセット 57 sender.setTranslation(.zero, in: parentViewController.view) 58 } 59 } 60}

イメージ説明

##両方 superView の配下におくのであれば

UIImageView にタグをつけて、それで検索することになるのかもしれません。

Swift

1 // 検索用のタグ 2 var tag = 1 3 4 //長押しされたら 5 @objc func longPress(_ sender: UILongPressGestureRecognizer){ 6 if sender.state == .began { 7 if let parentViewController = parent as? ViewController { 8 let parentWidth = parentViewController.view.frame.width 9 let height = view.frame.height + 48 10 let imageWidth = parentWidth / 4 11 12 let x = imageWidth * CGFloat(Int.random(in: 0...3)) 13 let y = height + imageWidth * CGFloat(Int.random(in: 0...3)) 14 15 let baseImageView = UIImageView(frame: CGRect(x: x, y: y, width: parentWidth / 4, height: parentWidth / 4)) 16 //let upperImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: parentWidth / 4, height: parentWidth / 4)) 17 let upperImageView = UIImageView(frame: CGRect(x: x, y: y, width: parentWidth / 4, height: parentWidth / 4)) 18 19 baseImageView.image = UIImage() 20 baseImageView.backgroundColor = .orange 21 22 upperImageView.image = UIImage(systemName: "calendar.circle.fill") 23 24 // 両方の imageView にタグをつける 25 baseImageView.tag = tag 26 upperImageView.tag = tag + 100 27 tag += 1 28 29 let panGesture = UIPanGestureRecognizer(target: self, action: #selector(moveView(sender:))) 30 31 baseImageView.addGestureRecognizer(panGesture) 32 baseImageView.isUserInteractionEnabled = true 33 34 parentViewController.view.addSubview(baseImageView) 35 parentViewController.view.addSubview(upperImageView) 36 } 37 } 38 } 39 40 @objc func moveView(sender: UIPanGestureRecognizer) { 41 if let parentViewController = parent as? ViewController, let baseImageView = sender.view as? UIImageView { 42 let location = sender.translation(in: parentViewController.view) 43 44 baseImageView.center.x += location.x 45 baseImageView.center.y += location.y 46 47 // タグを使って upperImageView を探す 48 let tag = baseImageView.tag 49 print(tag) 50 if let upperImageView = parentViewController.view.viewWithTag(tag + 100) as? UIImageView { 51 upperImageView.center = baseImageView.center 52 } 53 54 // 移動量をリセット 55 sender.setTranslation(.zero, in: parentViewController.view) 56 } 57 } 58}

投稿2020/09/20 23:48

編集2020/09/21 11:00
TsukubaDepot

総合スコア5086

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

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

ponponpoo

2020/09/21 06:46

丁寧なご回答ありがとございます。 できれば、View1,2両方とも親View上に貼り付けてその動作を行いたいのですが、その場合はどのようにすれば良いのでしょうか…?
TsukubaDepot

2020/09/21 06:54

親View(ViewController)上に張り付いています。 ご提示いただいたイメージ図を基に、ViewController に Container View を貼り付け、その中の ViewController をContainerViewController に設定しています。 ContainerViewController からは、親VIew、つまり ViewController のインスタンスは if let parentViewController = parent as? ViewController という形でダウンキャストして確認し、parantViewController として得ていますので、親 VIew を直接操作しています。 View Hierarchy のキャプチャも回答に追記しますので、ご確認いただければと思います。
ponponpoo

2020/09/21 08:41

ありがとうございます。 ほんとに初心者で説明がままならなくて申し訳ないのですが、 親 view >view1 親View > view2 にしたいです…。 view1,2両方とも親から見てsubviewの存在に出来ればと思っております。 もし、私の理解が追いついてなく、既にそのような構造になっておりましたらすみません…。
TsukubaDepot

2020/09/21 10:40

どうしてそのような構造にする必要があるのでしょうか。 不可能ではないと思いますが、そのようにしなければならない理由がわかれば、解決法が異なってくるかもしれません。
TsukubaDepot

2020/09/21 11:01

一応、両方直接 superView におく方法を追記してみましたのでご確認ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問