核心运动Swift闭包问题

3

我希望你能协助将一个旧的基于obj-c语言编写的游戏应用程序转换成新的swift代码。在使用"startAccelerometerUpdatesToQueue"方法时,我遇到了一些理解swift闭包及其使用的问题。

我已按以下方式初始化了motion manager:

motionManager!.accelerometerUpdateInterval = (1/40)

在我的视图控制器的viewDidLoad方法中。
var queue:NSOperationQueue
motionManager?.startAccelerometerUpdatesToQueue(queue, withHandler: {(accelerometerData :     CMAccelerometerData, error : NSError) in


})

“startAccelerometerUpdatesToQueue”这个函数出现了错误,我认为我没有理解正确的闭包语法。有什么想法吗?
3个回答

7
实际上,你只是在闭包中的参数签名出错了——闭包中的参数需要是可选的(因为它们是从Objective-C传递过来的,可能为nil)。由于这个原因,所以你提供的参数不匹配现有的方法签名,因此会发生错误。
请查看iOS 8 API文档,它们也提供了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

}

0

CMMotionManager

对象是 iOS 提供的运动服务的入口。这些服务为应用程序提供加速度计数据、旋转速率数据、磁力计数据和其他设备运动数据,例如姿态。这些类型的数据源于设备的加速度计和(在某些型号上)其磁力计陀螺仪

按指定间隔处理运动更新

要按特定间隔接收运动数据,应用程序调用一个“启动”方法,该方法需要一个操作队列(NSOperationQueue 的实例)和一个特定类型的块处理程序来处理这些更新。运动数据传递到块处理程序中。更新频率由“间隔”属性的值确定。

  • 加速度计。

设置 accelerometerUpdateInterval 属性以指定更新间隔。调用 startAccelerometerUpdatesToQueue:withHandler: 方法,传入一个类型为 CMAccelerometerHandler 的块。加速度计数据作为 CMAccelerometerData 对象传递到块中。

  • 陀螺仪。

  • 磁力计。

  • 设备动作。

以秒为单位提供加速度计更新给块处理程序的间隔。

声明

SWIFT

var accelerometerUpdateInterval: NSTimeInterval

讨论 系统会按照此属性的值确定的规律间隔向startAccelerometerUpdatesToQueue:withHandler中指定的块处理程序提供加速度计更新数据。

这个时间间隔的单位是秒。此属性的值有最小值和最大值的限制;最大值由硬件支持的最大频率决定。如果您的应用程序对加速度数据的时间间隔敏感,它应该总是检查传递的CMAccelerometerData实例的时间戳,以确定真正的更新间隔。

可用性 在iOS 4.0及更高版本中可用。


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)
        }
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接