19.CoreMotion(陀螺仪)

来源:互联网 发布:好莱坞电影推荐 知乎 编辑:程序博客网 时间:2024/05/16 18:22

CoreMotion

CoreMotion可以监听x,y,z上个方向的加速度, 它的使用还是蛮简单的, 下面我们学习如何使用它

1. 使用CoreMotion控制小球

import UIKitimport CoreMotionclass ViewController: UIViewController, UIAccelerometerDelegate {    let motionManager = CMMotionManager()    // 速度    var starSpeedX: UIAccelerationValue = 0.0    var starSpeedY: UIAccelerationValue = 0.0    var star: UIImageView!    // 使用加速度传感器控制图片的移动    override func viewDidLoad() {        super.viewDidLoad()        star = UIImageView(image: UIImage(named: "thumbHighlighted"))        star.frame = CGRect(x: 0, y: 0, width: 100, height: 100)        star.center = self.view.center        self.view.addSubview(star)        // startAccelerometerUpdatesToQueue的handler的运行间隔        motionManager.accelerometerUpdateInterval = 1.0 / 60.0        if motionManager.accelerometerAvailable {            let queue = NSOperationQueue.currentQueue()            motionManager.startAccelerometerUpdatesToQueue(queue!, withHandler: { (cMAccelerometerData, error) -> Void in                self.starSpeedX += cMAccelerometerData!.acceleration.x                self.starSpeedY += cMAccelerometerData!.acceleration.y                let posX = Double(self.star.center.x) + self.starSpeedX                let posY = Double(self.star.center.y) + self.starSpeedY                self.star.center = CGPoint(x: posX, y: posY)            })        }    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }}

运行程序, 模拟器貌似没法测试, 使用真机测试即可

从上面的代码可以看出, CoreMotion的使用还是很简单的:

首先初始化一个CMMotionManager()
然后设置时间间隔accelerometerUpdateInterval
最后使用startAccelerometerUpdatesToQueue:withHandler:开启监听

2. startAccelerometerUpdatesToQueue:withHandler:详解

我们查看它的定义:

public func startAccelerometerUpdatesToQueue(queue: NSOperationQueue, withHandler handler: CMAccelerometerHandler)第一个参数: 是一个NSOperationQueue, 多线程中会介绍, 这里先忽略第二个参数: 是一个CMAccelerometerHandler

我们查看CMAccelerometerHandler的定义:

public typealias CMAccelerometerHandler = (CMAccelerometerData?, NSError?) -> Void它就是一个block的别名, 它有两个参数, CMAccelerometerData?和NSError?

我们具体看一下CMAccelerometerData的定义:

@available(iOS 4.0, *)public class CMAccelerometerData : CMLogItem {    // 陀螺仪检测出的加速度    public var acceleration: CMAcceleration { get }}

我们发现它只有一个只读成员acceleration,他是CMAcceleration类型的, 我们进一步看看CMAcceleration的定义:

public struct CMAcceleration {    public var x: Double    public var y: Double    public var z: Double    public init()    public init(x: Double, y: Double, z: Double)}

它是一个结构体, 包含x,y,z三个方向的加速度

现在非常明了了, 我们在startAccelerometerUpdatesToQueue:withHandler:的CMAccelerometerHandler中就可以获得x,y,z的加速度

停止使用,我们可以使用CMMotionManager的:

 public func stopAccelerometerUpdates()

除此之外, CoreMotion还可以获得旋转和重力加速度

全部代码

import UIKitimport CoreMotionclass ViewController: UIViewController, UIAccelerometerDelegate {    let motionManager = CMMotionManager()    // 速度    var starSpeedX: UIAccelerationValue = 0.0    var starSpeedY: UIAccelerationValue = 0.0    var star: UIImageView!    // 使用加速度传感器控制图片的移动    override func viewDidLoad() {        super.viewDidLoad()        star = UIImageView(image: UIImage(named: "thumbHighlighted"))        star.frame = CGRect(x: 0, y: 0, width: 100, height: 100)        star.center = self.view.center        self.view.addSubview(star)        // startAccelerometerUpdatesToQueue的handler的运行间隔        motionManager.accelerometerUpdateInterval = 1.0 / 60.0        if motionManager.accelerometerAvailable {            let queue = NSOperationQueue.currentQueue()            motionManager.startAccelerometerUpdatesToQueue(queue!, withHandler: { (cMAccelerometerData, error) -> Void in                self.starSpeedX += cMAccelerometerData!.acceleration.x                self.starSpeedY += cMAccelerometerData!.acceleration.y                let posX = Double(self.star.center.x) + self.starSpeedX                let posY = Double(self.star.center.y) + self.starSpeedY                self.star.center = CGPoint(x: posX, y: posY)            })        }    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }}
1 0