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

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

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

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

Swift

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

iPhone

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

Q&A

解決済

1回答

1469閲覧

加速度センサによって動く画像を、ドラッグしている時だけ止めたいです。

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/11 17:49

現状のswiftの動き

①タップすると画像が現れる。
②傾けると加速度センサによって画像が動く。
③ドラッグ(?)すると、画像がついてくる。  ←今回修正したい部分
④再度タップすると画像が消える。

実現したいこと

加速度センサによって動く画像を、ドラッグした時のみ加速度センサの動きを止めたいです。

しかし現状では、加速度センサも加わり、下に傾けた状態だと、上にドラッグしても下に動いてしまいます。
ここをドラッグしている時は、加速度センサに左右されないようにし、
再度、指を離すと加速度センサによって、傾かせた方向に動かしたいです。

試した事

ロングプレスの時に、加速度を止める。と言うようなコードを入力するのかなと思ったのですが、
加速度を止める。と言うコードが分からず、できませんでした。

@IBAction func longTap(_ sender: UILongPressGestureRecognizer) {
}
上記のコードに、加速度を止めると言う、コードを入力すればできるのでしょうか??

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

該当のソースコード

import UIKit import CoreMotion class ViewController: UIViewController { var coin = UIImageView() var coinCount = 0 @IBAction func addImage(_ sender: UITapGestureRecognizer) { if coinCount == 0 { coin = UIImageView(image: UIImage(named: "daiya")) coin.frame = CGRect(x: 0, y: 0, width: 110, height: 110) coin.center = sender.location(in: self.view) coin.contentMode = .scaleToFill coin.clipsToBounds = true coin.center = sender.location(in: self.view) UIView.animate(withDuration: 0.10, animations: { }) { (Bool) -> Void in } self.view.addSubview(coin) } else if coinCount == 1 { coin.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: coin) // 移動する前の座標を取得. let prevLocation = aTouch.previousLocation(in: coin) // CGRect生成. var myFrame: CGRect = coin.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を追加. coin.frame = myFrame } let cmManager = CMMotionManager() let scrSize: CGSize = UIScreen.main.bounds.size let mag: Double = 1.0 var vx, vy: Double? override func viewDidLoad() { super.viewDidLoad() vx = 0.0 vy = 0.0 startGame() } func startGame() { cmManager.deviceMotionUpdateInterval = 0.03 let handler: CMDeviceMotionHandler = { (motionData: CMDeviceMotion?, error: Error?) -> Void in self.stepGame(motionData: motionData, error: error) } cmManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: handler) } func stepGame(motionData: CMDeviceMotion?, error: Error?) { var xMin, xMax, yMin, yMax: Int xMin = Int(coin.frame.width / 2) xMax = Int(scrSize.width) - xMin yMin = Int(coin.frame.height / 2) yMax = Int(scrSize.height) - yMin if let motion = motionData { let gravity = motion.gravity vx = vx! + gravity.x * mag vy = vy! - gravity.y * mag var x: Int = Int(Double(coin.center.x) + vx!) var y: Int = Int(Double(coin.center.y) + vy!) if (x < xMin) { x = xMin; vx = 0.0 } else if (x > xMax) { x = xMax; vx = 0.0 } if (y < yMin) { y = yMin; vy = 0.0 } else if (y > yMax) { y = yMax; vy = 0.0 } coin.center = CGPoint(x: x,y: y) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }

使用している言語

swift
Xvode 11.4

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

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

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

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

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

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

guest

回答1

0

ベストアンサー

cmManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: handler)

ここで重力加速度などの変化に応じた処理をクロージャという形で登録し、処理を開始しています。

startDeviceMotionUpdates(to:withHandler:)で登録した処理を解除するのはstopDeviceMotionUpdates()となっているようです。

Instance Method stopDeviceMotionUpdates() Stops device-motion updates.

詳しくは上記の公式ドキュメント(やXcodeのクイックヘルプから参照できるドキュメント)を見てみてください。

おそらく、タッチ開始とタッチ終了も検知させ、タッチ開始時に加速度処理の中止を行い、タッチ終了後に加速度処理の開始を行うようなながれになるのではないでしょうか。

投稿2020/04/12 01:58

TsukubaDepot

総合スコア5086

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

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

magiee

2020/04/12 03:17

タッチ開始の処理は下記のコードだと思うのですが、これを入力すると、そもそも加速度センサが反応しません。 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { } 実際に入力しているコード↓ func startGame() { cmManager.deviceMotionUpdateInterval = 0.03 let handler: CMDeviceMotionHandler = { (motionData: CMDeviceMotion?, error: Error?) -> Void in self.stepGame(motionData: motionData, error: error) } cmManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: handler) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { cmManager.stopDeviceMotionUpdates() } です。どのように修正すればよろしいでしょうか。
TsukubaDepot

2020/04/12 04:48

試しにこちらでもやってみましたが、ドラッグ中だけ加速度センサを無効にすることは可能です。 要点だけ書けば、 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { cmManager.stopDeviceMotionUpdates() } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { startGame() } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { print("touchesMoved") // ここ以降はオリジナル通り } です。 もしかして、touchMoved()の処理まで削除していないでしょうか。 1. タッチ開始の処理 -> ここで重力加速度の処理を一旦中止する。 2. 達継続中の処理 -> 移動させたいビューを移動させる 3. タッチ終了時の処理 -> 再び重力加速度の処理を再開させる という流れです。 もちろん、これ以外の流れにしたいのであれば、そのように要件を整理して、コーディングする必要はありますね。
magiee

2020/04/12 06:07

回答していただきありがとうございました。 単純なミスで、 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { startGame() } のコードを入力しておりませんでした。 いつも、丁寧に解説して頂き、ありがとうございます。 余談で申し訳ないのですが、 touchesBegan touchesEnded のコードを入力すると、最初にタップして表示させた画像が止まっており、加速度センサが反応しませんでしたが、 @IBAction func addImage(_ sender: UITapGestureRecognizer) {  //中略// startGame() } と、すると加速度センサが反応するようになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問