我有一个 UIView,我希望它始终朝上。因此,假设您有一个带有箭头的 UIImageView,无论设备以何种方式握持,它都指向上方。显然我需要加速度计,但是告诉它根据坐标旋转图像只会在我第一次想到的时候起作用,因为旋转是相对的。有没有更简单的方法来做到这一点?我觉得在某个地方会有一个简单的示例应用程序可以做这样的事情。
3 回答
Apple 有完全符合您要求的示例代码;看看这个:http: //developer.apple.com/library/ios/#samplecode/WhichWayIsUp/Introduction/Intro.html
要接收特定的运动数据,请使用它的共享实例UIAccelerometer
及其委托。 http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAccelerometerDelegate_Protocol/UIAccelerometerDelegate/UIAccelerometerDelegate.html#//apple_ref/occ/intf/UIAccelerometerDelegate
至于轮换,我不确定。在此处查看“BubbleLevel”示例代码:http: //developer.apple.com/library/ios/samplecode/BubbleLevel/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007331
加速度计委托文档引用了该文件和其他相关示例代码。
WhichWayIsUp是您正在寻找的示例应用程序 - 在 iOS 参考库中(很棒的文档!)
应用于视图的变换不是累积的。相反,视图开始与其父级的坐标系对齐,并且相对于该坐标系应用变换。
正如其他答案所暗示的那样,Apple 的BubbleLevel 示例代码中有足够的部分来完成您正在寻找的内容。-[LevelViewController accelerometer:didAccelerate:]
已经包含如何提取重力矢量的平滑屏幕相对旋转分量的示例:
// Use a basic low-pass filter to only keep the gravity in the accelerometer values for the X and Y axes
accelerationX = acceleration.x * kFilteringFactor + accelerationX * (1.0 - kFilteringFactor);
accelerationY = acceleration.y * kFilteringFactor + accelerationY * (1.0 - kFilteringFactor);
// keep the raw reading, to use during calibrations
currentRawReading = atan2(accelerationY, accelerationX);
鉴于UIAcceleration和atan2的坐标系,您需要牢记以下几个因素来计算视图所需的旋转:
- 当设备竖直竖立时,
atan2
将返回 -π/2 (-90°),因为输入的重力矢量为 {0.0, -1.0, 0.0}。 CGAffineTransformMakeRotation
创建一个将顺时针(在 iOS 上)旋转指定弧度数的变换,但原始角度 fromatan2
指定逆时针旋转。
因此,您需要将视图旋转 -(currentRawReading + π/2),假设其父视图与屏幕纵向对齐:
view.transform = CGAffineTransformMakeRotation(-(currentRawReading + M_PI/2));