如何在旋转前检测iPhone方向

12 iphone cocoa-touch objective-c iphone-sdk-3.0

在我的程序中,我根据旋转移动东西,但我不是在旋转整个视图.我正在使用 :

  static UIDeviceOrientation previousOrientation = UIDeviceOrientationPortrait;

 - (void)applicationDidFinishLaunching:(UIApplication *)application {   
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
    [[NSNotificationCenter defaultCenter] addObserver:self
           selector:@selector(didRotate:)
           name:@"UIDeviceOrientationDidChangeNotification" object:nil];

}

- (void) didRotate:(NSNotification *)notification{  
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    [self doRotationStuff:orientation: previousOrientation];
previousOrientation = orientation;

} 
Run Code Online (Sandbox Code Playgroud)

只要程序启动时,设备方向是纵向,但如果初始方向是横向或颠倒,则无效,因为[self doRotationStuff]相对于与前一个方向的差异进行更改.

有没有办法在发射时或在旋转设备之前检测方向?

del*_*any 12

根据您的具体情况,更简单的选项可能是UIViewController类的interfaceOrientation属性.在轮换之前这是正确的.

  • 谢谢!我不知道htat字段是否存在 - 我正在使用UIDevice的方向,这不是很有帮助. (2认同)

Dan*_*son 3

更新:

[UIDevice currentDevice].orientation因此,从评论讨论来看,在方向第一次真正改变之前你不能依赖。如果是这样,您可能可以通过获取原始加速度计读数来破解它。

#define kUpdateFrequency 30  // Hz
#define kUpdateCount 15 // So we init after half a second
#define kFilteringFactor (1.0f / kUpdateCount)

- (void)applicationDidFinishLaunching:(UIApplication *)app
{
    [UIAccelerometer sharedAccelerometer].updateInterval = (1.0 / kUpdateFrequency);
    [UIAccelerometer sharedAccelerometer].delegate = self;
    accelerometerCounter = 0;
    ...
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)accel
{
    // Average out the first kUpdateCount readings
    // acceleration_[xyz] are ivars typed float
    acceleration_x = (float)accel.x * kFilteringFactor + acceleration_x * (1.0f - kFilteringFactor);
    acceleration_y = (float)accel.y * kFilteringFactor + acceleration_y * (1.0f - kFilteringFactor);
    acceleration_z = (float)accel.z * kFilteringFactor + acceleration_z * (1.0f - kFilteringFactor);

    accelerometerCounter++;
    if (accelerometerCounter == kUpdateCount)
    {
        [self initOrientation];
        [UIAccelerometer sharedAccelerometer].delegate = nil;
    }
}

- (void)initOrientation
{
    // Figure out orientation from acceleration_[xyz] and set up your UI...
}
Run Code Online (Sandbox Code Playgroud)

原始回复:

期间是否[UIDevice currentDevice].orientation返回正确的方向applicationDidFinishLaunching:?如果是这样,您可以根据该方向设置初始 UI。

如果该属性直到稍后才设置,您可以尝试performSelector:afterDelay:在短暂的延迟后初始化 UI。

此代码示例来自下面 Kendall 的回答,为了完整性而添加到此处:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];
Run Code Online (Sandbox Code Playgroud)

我不确定零秒延迟是否足够——这意味着 的代码getOriented将在第一次通过事件运行循环期间运行。您可能需要等待更长的时间才能在 上注册加速度计读数UIDevice