如何在旋转前检测iPhone方向

时间:2009-07-21 17:36:36

标签: iphone objective-c cocoa-touch 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;

} 

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

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

7 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分: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...
}

原始回复:

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

如果该属性直到稍后才设置,您可能会尝试使用performSelector:afterDelay:在稍微延迟后初始化UI。

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

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];

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

答案 2 :(得分:1)

莫尔,这些答案似乎有点像红鲱鱼;我不明白为什么你不能为UIViewController类使用以下内置方法:

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {}

在旋转发生后自动调用此方法(而不是使用shouldAutorotateToInterfaceOrientation,它只会告诉您即将发生)。方便地,变量'fromInterfaceOrientation'包含先前的方向。正如文档中所述,您可以假设视图的interfaceOrientation属性已经设置为新方向,因此您可以使用一个方法来访问旧方向和新方向!

如果我错过了某些内容并且您已经解雇了能够使用此方法的话,我很抱歉!在上述方法中免费提供变量时,您正在为“之前的方向”创建和存储变量,这似乎很奇怪。

希望有所帮助!

答案 3 :(得分:1)

如果您需要确定指向的方式,请将其用于UI的方向。

不是100%肯定这是正确的,但是我不知道如何:

[[[UIApplication sharedApplication] statusBar] orientation]

答案 4 :(得分:1)

这是在应用程序首次加载且UIDeviceOrientation设置为UIDeviceOrientationUnknown时获取方向的一种方法。您可以查看旋转视图的transform属性。

if(toInterface == UIDeviceOrientationUnknown) {
    CGAffineTransform trans = navigationController.view.transform;
    if(trans.b == 1 && trans.c == -1)
        toInterface = UIDeviceOrientationLandscapeLeft;
    else if(trans.b == -1 && trans.c == 1)
        toInterface = UIDeviceOrientationLandscapeRight;
    else if(trans.a == -1 && trans.d == -1)
        toInterface = UIDeviceOrientationPortraitUpsideDown;
    else
        toInterface = UIDeviceOrientationPortrait;
}

答案 5 :(得分:0)

可以找到有关如何从加速器读数获取设备方向的更完整示例here 由于解决方案依赖于加速器读数,因此无法在模拟器上运行,因此您必须在设备上工作......仍然在寻找可在模拟器上运行的解决方案。

答案 6 :(得分:-1)

在回复你的评论时,我认为我最好把代码放在这里而不是评论中(虽然丹尼尔值得赞扬):

在applicationDidFinishLaunching中:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];

然后你只需要调用方法:

- (void) getOriented 
{ 
   UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
   // save orientation somewhere
}