无论设备方向如何,如何保持 UIView 指向某个方向?

发布于 2024-10-15 03:58:38 字数 155 浏览 1 评论 0 原文

我有一个 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无名指的心愿 2024-10-22 03:58:38

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/UIAccelerometerDelegate

As 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.

孤独岁月 2024-10-22 03:58:38

WhichWayIsUp 是您正在寻找的示例应用程序 - 在 iOS 参考库中(很棒的文档!)

WhichWayIsUp is the sample application you're looking for - in iOS Reference Library (great docs!)

蛮可爱 2024-10-22 03:58:38

应用于视图的变换不是累积的。相反,视图开始与其父级的坐标系对齐,并且相对于该视图应用变换。

正如其他答案所提到的,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);

给定 UIAccelerationatan2,计算视图所需的旋转时需要记住几个因素:

  1. 当设备纵向直立时,atan2 将返回-π/2 (-90°),因为输入重力矢量为{0.0, -1.0, 0.0}。
  2. CGAffineTransformMakeRotation 创建一个将顺时针旋转(在 iOS 上)指定弧度数的变换,但来自 atan2 的原始角度指定逆时针旋转。

因此,您需要将视图旋转 -(currentRawReading + π/2),假设其父视图面向屏幕纵向:

view.transform = CGAffineTransformMakeRotation(-(currentRawReading + M_PI/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:

// 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);

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:

  1. When the device is upright in portrait, atan2 will return -π/2 (-90°), since the input gravity vector is {0.0, -1.0, 0.0}.
  2. CGAffineTransformMakeRotation creates a transform that will rotate clockwise (on iOS) by the specified number of radians, but the raw angle from atan2 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:

view.transform = CGAffineTransformMakeRotation(-(currentRawReading + M_PI/2));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文