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

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

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

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

Swift

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

iPhone

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

Q&A

解決済

1回答

422閲覧

CMDeviceMotionHandlerについて分からない所があります。

magiee

総合スコア28

Xcode

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

Swift

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

iPhone

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

0グッド

1クリップ

投稿2020/04/10 18:52

前提・実現したいこと

練習で下記のリンクと同じものを作りたいのですが、
少し古いみたいで、コードにエラーが発生してしまいます。

参考にしているリンク
https://nw.tsuda.ac.jp/lec/swift/SwiftGravity/

エラーが出ているのは、下記のコード

let handler: CMDeviceMotionHandler = { (motionData: CMDeviceMotion?, error: NSError?) -> Void in self.stepGame(motionData, error: error) } cmManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: handler) }

調べたところ、NSErrorのNSを取れば、エラーは消えると言うリンクも見つけたのですが、消えませんでした。
消えると書いてあったリンク
http://yatsurecreate.com/2017/03/31/swift%E3%81%A7%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%81%AE%E5%80%A4%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%A7%E3%82%A8/

どうしても、うまくいかないので、
ご教授のほど、よろしくお願い致します。

該当のソースコード全文

import UIKit import CoreMotion class ViewController: UIViewController { @IBOutlet weak var myBall: UIImageView! let cmManager = CMMotionManager() let scrSize: CGSize = UIScreen.mainScreen().bounds.size let mag: Double = 20.0 var vx, vy: Double? override func viewDidLoad() { super.viewDidLoad() vx = 0.0 vy = 0.0 startGame() } func startGame() { cmManager.deviceMotionUpdateInterval = 0.1 let handler: CMDeviceMotionHandler = { (motionData: CMDeviceMotion?, error: NSError?) -> Void in self.stepGame(motionData, error: error) } cmManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: handler) } func stepGame(motionData: CMDeviceMotion?, error: NSError?) { var xMin, xMax, yMin, yMax: Int xMin = Int(myBall.frame.width / 2) xMax = Int(scrSize.width) - xMin yMin = Int(myBall.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(myBall.center.x) + vx!) var y: Int = Int(Double(myBall.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 } myBall.center = CGPoint(x: x,y: y) } } override func didReceiveMemoryWarning() { at can be recreated. } }

使用している言語

swift
Xvode 11.4

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

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

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

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

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

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

guest

回答1

0

ベストアンサー

CMDeviceMotionHandlerの型は(CMDeviceMotion?, Error?) -> Voidと定義されています( Xcode上でCMDeviceMotionHandlerの部分にマウスポインタを合わせて、Optionを押しながらクリックするとヘルプが表示されるので、それも見てみてください)。

なので、

swift

1func startGame() { 2 cmManager.deviceMotionUpdateInterval = 0.1 3 let handler: CMDeviceMotionHandler = { 4 (motionData: CMDeviceMotion?, error: NSError?) -> Void in 5 self.stepGame(motionData, error: error) 6 } 7 cmManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: handler) 8 }

error: NSError?の部分はerror: Error?に書き換える必要があります。

ただ、これについてはXcodeがエラーを出しつつも、修正案を Fix という形で提案してくれるので、それに従えば大丈夫です。

しかし、この変更を加えたことで、今度は別の問題が発生します。

それは、

swift

1self.stepGame(motionData, error: error)

の部分です。

このメソッドの定義部分を見ると、

swift

1 func stepGame(motionData: CMDeviceMotion?, error: NSError?) {

となっていますが、ここのNSError?Errorに修正する必要があります。ここは自動では修正案が出てきませんので、手動で修正する必要があります。

ほかにも、全体的に古いコードなのでSwift5で実行するのであればあちこちでエラーがでますが、すべて修正案に従えば動くと思います。

投稿2020/04/11 01:26

TsukubaDepot

総合スコア5086

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

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

magiee

2020/04/11 02:39

cmManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: handler)  を cmManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: handler) self.stepGame(motionData, error: error)  を self.stepGame(motionData: motionData, error: error) に書き換えると動くようになりました! ありがとうございます。とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問