我有一个 UIView,我希望它始终朝上。假设您有一个带有箭头的 UIImageView,无论以何种方式握住设备,它都会指向上方。显然我需要加速度计,但告诉它根据坐标旋转图像只会在我认为第一次起作用,因为旋转是相对的。有更简单的方法吗?我觉得某个地方会有一个简单的示例应用程序可以执行类似的操作。
I have a UIView that I want to always be facing up. So say you have an UIImageView that has an arrow, and no matter what way the device is being held, it's pointing up. Obviously I need the accelerometer, but telling it to rotate the image based on the coordinates is only going to work the first time I think, since rotations are relative. Is there an easier way of doing this? I feel like there would be a simple example app somewhere that would do something like this.
发布评论
评论(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
加速度计委托文档引用了以及其他相关示例代码。
Apple has sample code which does exactly what you want; have a look at this: http://developer.apple.com/library/ios/#samplecode/WhichWayIsUp/Introduction/Intro.html
To receive specific motion data, use the shared instance of
UIAccelerometer
and it's delegate. http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAccelerometerDelegate_Protocol/UIAccelerometerDelegate/UIAccelerometerDelegate.html#//apple_ref/occ/intf/UIAccelerometerDelegateAs far as the rotations, I'm not sure. Have a look at the "BubbleLevel" sample code here: http://developer.apple.com/library/ios/samplecode/BubbleLevel/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007331
The accelerometer delegate documentation references that and other relevant sample code.
WhichWayIsUp 是您正在寻找的示例应用程序 - 在 iOS 参考库中(很棒的文档!)
WhichWayIsUp is the sample application you're looking for - in iOS Reference Library (great docs!)
应用于视图的变换不是累积的。相反,视图开始与其父级的坐标系对齐,并且相对于该视图应用变换。
正如其他答案所提到的,Apple 的 BubbleLevel 示例代码 实现您正在寻找的目标。
-[LevelViewController accelerometer:didAccelerate:]
已经包含了如何提取重力矢量的平滑屏幕相对旋转分量的示例:给定 UIAcceleration 和 atan2,计算视图所需的旋转时需要记住几个因素:
atan2
将返回-π/2 (-90°),因为输入重力矢量为{0.0, -1.0, 0.0}。CGAffineTransformMakeRotation
创建一个将顺时针旋转(在 iOS 上)指定弧度数的变换,但来自atan2
的原始角度指定逆时针旋转。因此,您需要将视图旋转 -(currentRawReading + π/2),假设其父视图面向屏幕纵向:
Transforms applied to a view aren’t cumulative. Rather, the view starts out being aligned to the coordinate system of its parent, and the transform is applied relative to that.
As other answers have alluded to, there are enough pieces in Apple’s BubbleLevel sample code to accomplish what you’re looking for.
-[LevelViewController accelerometer:didAccelerate:]
already contains an example of how to extract the smoothed screen-relative rotation component of the gravity vector:Given the coordinate systems of UIAcceleration and atan2, there are a few factors you’ll need to keep in mind to calculate your view’s desired rotation:
atan2
will return -π/2 (-90°), since the input gravity vector is {0.0, -1.0, 0.0}.CGAffineTransformMakeRotation
creates a transform that will rotate clockwise (on iOS) by the specified number of radians, but the raw angle fromatan2
specifies a counterclockwise rotation.Accordingly, you’ll want to rotate your view by -(currentRawReading + π/2), assuming its parent view is oriented with the screen in portrait: