我正在尝试将obj-c中构建的旧游戏应用程序转换为新的swift代码。我在解决swift闭包以及如何在“startAccelerometerUpdatesToQueue”方法中使用它们时遇到了一些问题。
我已经用这种方式初始化了运动管理器
motionManager!.accelerometerUpdateInterval = (1/40)
然后在我的视图控制器的viewdidload中
var queue:NSOperationQueue
motionManager?.startAccelerometerUpdatesToQueue(queue, withHandler: {(accelerometerData : CMAccelerometerData, error : NSError) in
})
有什么想法吗?
答案 0 :(得分:6)
实际上,你只是签名错了 - 你的闭包的参数需要是选项(因为它们是从Objective-C传递的,它们可能是nil
)。因此,您提供的参数与现有方法签名不匹配,因此您会收到错误。
看看iOS 8 API docs,他们还提供Swift签名:
func startAccelerometerUpdatesToQueue(_ queue: NSOperationQueue!,
withHandler handler: CMAccelerometerHandler!)
和CMAccelerometerHandler
定义为
typealias CMAccelerometerHandler = (CMAccelerometerData!, NSError!) -> Void
因此,您的电话应该是:
motionManager?.startAccelerometerUpdatesToQueue(queue, withHandler: {(accelerometerData : CMAccelerometerData!, error : NSError!) in
})
与任何以闭包作为最后一个参数的函数/方法一样,你可以将它从参数列表中删除并在调用之后写入它(尾随闭包语法 - 这个例子也省略了类型,因为它们可以推断,但这是可选的):
motionManager?.startAccelerometerUpdatesToQueue(queue) { accelerometerData, error in
}
答案 1 :(得分:0)
object是iOS提供的运动服务的入口。这些服务为应用提供加速度计数据,旋转速度数据,磁力计数据以及其他设备动态数据,例如态度。这些类型的数据来自设备的加速度计和(在某些型号上)其磁力计和陀螺仪。
要以特定的时间间隔接收动作数据,应用程序会调用一个“start”方法,该方法接受一个操作队列( NSOperationQueue 的实例)和一个特定类型的块处理程序来处理这些更新。运动数据被传递到块处理程序中。更新频率由“interval”属性的值决定。
设置 accelerometerUpdateInterval 属性以指定更新间隔。调用 startAccelerometerUpdatesToQueue:withHandler:方法,传入 CMAccelerometerHandler 类型的块。加速度计数据作为 CMAccelerometerData 对象传递到块中。
陀螺
磁力。
设备动作。
<强>声明强>
SWIFT
var accelerometerUpdateInterval:NSTimeInterval
<强>讨论强> 系统为 startAccelerometerUpdatesToQueue:withHandler 中指定的块处理程序提供加速度计更新:定期由此属性的值确定。
间隔单位以秒为单位。此属性的值上限为最小值和最大值;最大值由硬件支持的最大频率决定。如果您的应用程序对加速数据的间隔敏感,则应始终检查已交付的 CMAccelerometerData 实例的时间戳,以确定真正的更新间隔。
状况 适用于iOS 4.0及更高版本。
答案 2 :(得分:0)
import UIKit
import CoreMotion
class ViewController: UIViewController {
let motionManager = CMMotionManager()
var timer: Timer!
override func viewDidLoad() {
super.viewDidLoad()
motionManager.startAccelerometerUpdates()
motionManager.startGyroUpdates()
motionManager.startMagnetometerUpdates()
motionManager.startDeviceMotionUpdates()
timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true)
}
@objc func update() {
if let accelerometerData = motionManager.accelerometerData {
print(accelerometerData)
}
if let gyroData = motionManager.gyroData {
print(gyroData)
}
if let magnetometerData = motionManager.magnetometerData {
print(magnetometerData)
}
if let deviceMotion = motionManager.deviceMotion {
print(deviceMotion)
}
}
}