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

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

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

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

2回答

1755閲覧

touchesMovedで、ドラッグしていると反応しなくなります。これってコードの問題でしょうか?

magiee

総合スコア28

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2020/04/09 11:09

改善したこと。

UILabelで作成した、myLabelをtouchesMovedで、動かしているのですが、
ドラッグし続けると、反応しなくなります。
これは、バグなのかコードの問題なのか、改善の余地はあるのか、教えていただきたいです。

下記に反応しなくなる時の動画のリンクと、コードの記載しています。
よろしくお願いいたします。

動画はyoutubeの方に限定公開で投稿してます。(他に動画の載せ方がありましたら教えて下さい。)
https://www.youtube.com/watch?v=0cSek_kRO3s

該当のソースコード

import UIKit class ViewController: UIViewController { var myLabel:UILabel! var coinCount = 0 @IBAction func addImage(_ sender: UITapGestureRecognizer) { // タップする(coinCount==0)とmyLabelが表示される。 if coinCount == 0 { myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 80, height: 80)) myLabel.text = "Drag!" myLabel.textAlignment = NSTextAlignment.center myLabel.backgroundColor = UIColor.red myLabel.layer.masksToBounds = true myLabel.center = sender.location(in: self.view) myLabel.layer.cornerRadius = 40.0 UIView.animate(withDuration: 0.10, animations: { // アニメーションをつける self.myLabel.transform = CGAffineTransform(scaleX: 1.5, y: 1.5) }) { (Bool) -> Void in } self.view.addSubview(myLabel) // 2回目のタップの時(coinCount==2)ラベルが消える。 } else if coinCount == 1 { myLabel.removeFromSuperview() } coinCount = coinCount + 1 coinCount = coinCount % 2 } // ドラッグした時のコード @IBAction override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { print("touchesMoved") let aTouch = touches.first! let location = aTouch.location(in: self.view) let prevLocation = aTouch.previousLocation(in: self.view) var myFrame: CGRect = self.view.frame // ドラッグで移動したx, y距離をとる. let deltaX: CGFloat = location.x - prevLocation.x let deltaY: CGFloat = location.y - prevLocation.y // 移動した分の距離をmyFrameの座標にプラスする. myFrame.origin.x += deltaX myFrame.origin.y += deltaY // frameにmyFrameを追加. self.view.frame = myFrame } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } }

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

エラーは特になし。

使用している言語

swift
Xvode 11.4

ご教授のほど、よろしくお願い致します。

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

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

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

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

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

hoshi-takanori

2020/04/09 19:17

touchesMoved で self.view (画面全体!) を動かしてるので、self.view がなくなった部分が反応しなくなるのだと思います。(self.view に背景色を指定したら何が起きてるか分かると思います。)
magiee

2020/04/09 23:51

背景色を指定したら、画面全体が動いていることが確認できました! とても分かりやすい説明ありがとうございます。 ちなみに、この画面全体の大きさは、サイズ変更できたりするのでしょうか? (画面の端までドラッグしても、タップを反応させるようにしたいです。)
hoshi-takanori

2020/04/09 23:56

サイズ変更以前に、self.view を動かすのは良くないので、myLabel を動かすべきだと思います。
magiee

2020/04/10 00:07

ご指摘ありがとうございます。 myLabelのみを動かすためには、どのようにコードを記載した方がよろしいのでしょうか? ご教授のほど、お願いいたします。
guest

回答2

0

ソースコードをこちらにもあげておきます。
https://github.com/Tetsukick/iOS_drag_drop_test/blob/master/README.md

投稿2020/04/10 03:56

Tetsukick

総合スコア297

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

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

0

ベストアンサー

原因

ドラッグ処理で、ViewController自体を動かしてしまっている。ことが原因です。
Capture View hierarchy

ViewControllerを水色に変更するとよりわかりやすいです。
以下キャプチャしました。
再現動画

修正方法

func touchesMoved内の操作対象をself.viewmyLabelに変更

修正後のソースコード

Swift:ViewController.swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 var myLabel: UILabel? 6 var coinCount = 0 7 8 9 10 @IBAction func addImage(_ sender: UITapGestureRecognizer) { 11 print("tapped") 12 13 // タップする(coinCount==0)とmyLabelが表示される。 14 if coinCount == 0 { 15 16 myLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 80, height: 80)) 17 if let myLabel = myLabel { 18 myLabel.text = "Drag!" 19 20 myLabel.textAlignment = NSTextAlignment.center 21 22 myLabel.backgroundColor = UIColor.red 23 24 myLabel.layer.masksToBounds = true 25 26 myLabel.center = sender.location(in: self.view) 27 28 myLabel.layer.cornerRadius = 40.0 29 30 UIView.animate(withDuration: 0.10, animations: { 31 32 // アニメーションをつける 33 34 myLabel.transform = CGAffineTransform(scaleX: 1.5, y: 1.5) 35 36 }) { (Bool) -> Void in 37 38 } 39 40 41 self.view.addSubview(myLabel) 42 } 43 44 // 2回目のタップの時(coinCount==2)ラベルが消える。 45 } else if coinCount == 1 { 46 myLabel?.removeFromSuperview() 47 } 48 49 coinCount = coinCount + 1 50 coinCount = coinCount % 2 51 52 } 53 54 // ドラッグした時のコード 55 @IBAction override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 56 print("touchesMoved") 57 58 guard let myLabel = myLabel else { return } 59 60 let aTouch = touches.first! 61 62 let location = aTouch.location(in: myLabel) 63 64 let prevLocation = aTouch.previousLocation(in: myLabel) 65 66 var myFrame: CGRect = myLabel.frame 67 68 // ドラッグで移動したx, y距離をとる. 69 70 let deltaX: CGFloat = location.x - prevLocation.x 71 72 let deltaY: CGFloat = location.y - prevLocation.y 73 74 75 // 移動した分の距離をmyFrameの座標にプラスする. 76 77 myFrame.origin.x += deltaX 78 79 myFrame.origin.y += deltaY 80 81 82 // frameにmyFrameを追加. 83 84 myLabel.frame = myFrame 85 86 } 87 88 89 override func viewDidLoad() { 90 super.viewDidLoad() 91 // Do any additional setup after loading the view. 92 } 93 94 95} 96

投稿2020/04/10 03:47

Tetsukick

総合スコア297

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

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

magiee

2020/04/10 13:28

とても丁寧に説明していただきありがとうございました!とても助かりました。 少し気になった事があるのですが、 ①print("tapped") と言うコードを記載してもしなくても、特にエラーなく動きました。 これは、どう言う理由なのでしょうか??? ② if coinCount == 0 { if let myLabel = myLabel { } } else if coinCount == 1 { } と、言うように、if文を使った後、さらにifを使っていますが、else は一つしか使用していなくて、 いらないのかな?っと疑問に思ったのですが、これはこう言う使い方もあるよっと言う認識でいいんですかねぇ。。。。
Tetsukick

2020/04/10 18:05

① こちらはデバッグようにprintさせていただけなので、気にせず、、 ② if coinCount == 0 { の後にmyLabelを代入してその後に、アンラップのためのif文を挿入しています。 つまり、Null対策のために必要です。
magiee

2020/04/10 18:35

解説していただきありがとうございます! 理解する事ができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問