我现在对此深有感触,所以当我翻转手机时,它会在文本中添加一个,但它会一直添加直到完成翻转。我有办法做到这一点,所以每次翻转都会增加一个。
更改y>代码
func startGyro() {
motionManager.gyroUpdateInterval = 0.2
motionManager.startGyroUpdates(to: OperationQueue.current!) { (data, Error) in
if let myData = data {
if myData.rotationRate.y > 3 {
tiltOut = tiltOut + 1
self.labelText = "\(tiltOut)"
}
}
}
}
我希望它每次翻转记录一次。
答案 0 :(得分:0)
将此代码视为代码示例,而不是复制粘贴示例,因为与陀螺仪相关的代码很难测试,但此处的核心思想是跟踪经过的时间和旋转速率,以确定与代码的距离。设备已旋转。
var prevTime = DispatchTime.now()
var totalRotation: CGFloat = 0
var delta: CGFloat = 10
func startGyro() {
motionManager.gyroUpdateInterval = 0.2
motionManager.startGyroUpdates(to: OperationQueue.current!) { (data, Error) in
if let myData = data {
let currTime = DispatchTime.now()
let dt = 0
let interval = prevTime.distance(to: currTime)
if case .nanoseconds(let value) = interval {
dt = value
}
prevTime = currTime
// assuming rotationRate is in degrees/millisecond.
let dTheta: CGFloat = CGFloat(myData.rotationRate.y) * CGFloat(dt)
// If not milliseconds, convert dt to correct time unit
// If rotationRate is in radians, convert to degrees or make future comparison check for 2*pi instead of 360 degrees
totalRotation += dTheta
if totalRotation > 360 - delta && totalRotation < 360 + delta {
tiltOut = tiltOut + 1
self.labelText = "\(tiltOut)"
totalRotation -= 360
}
}
}
}
存在增量是因为startGyroUpdates
不会在设备每次旋转1度时被调用,因此您必须提供一个缓冲区来确定“大约360度”可以做什么。在这里,我给出了一个范围,如果它已经旋转了350-370度,则应该将标签加1。当然,这使用的是离散的时间块,但是假设startGyroUpdates
调用与该时间段中rotationRate的变化之间的时间间隔相对较小,则应该不会出现太多错误。该代码还假设电话在startGyroUpdates
次通话之间不会旋转超过360度,这是一个公平的假设。
如果您知道旋转速度会相当恒定,则也可以使用旋转速度的平均值并将其乘以经过的时间。
编辑:在dTheta之前忘记了let
,并添加了将DispatchTimeInterval
转换为可用Int
的代码。您可以添加秒,毫秒等的大小写,并将dt
转换为rotationRate
的时间单位。有关将prevTime.distance(to: currTime)
的结果转换为可以进行数学运算的Int
的更多信息,请参见this SO link。确保进行单位转换时不会损失精度。
编辑2 :指定dTheta
类型为CGFloat
编辑3 :将myData.rotationRate.y
和dt
投射到CGFloat