旋转前如何检测iPhone的方向

旋转前如何检测iPhone的方向,iphone,objective-c,cocoa-touch,iphone-sdk-3.0,Iphone,Objective C,Cocoa Touch,Iphone Sdk 3.0,在我的程序中,我基于旋转移动对象,但我不会旋转整个视图。我正在使用: static UIDeviceOrientation previousOrientation = UIDeviceOrientationPortrait; - (void)applicationDidFinishLaunching:(UIApplication *)application { [window addSubview:viewController.view]; [window make

在我的程序中,我基于旋转移动对象,但我不会旋转整个视图。我正在使用:

  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]相对于上一方向的差异进行更改


有没有办法在启动时或设备旋转前检测方向?

更新:

因此,从评论讨论中可以看出,在方向第一次真正改变之前,您不能依赖
[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是否在
应用程序完成启动时返回正确的方向:
?如果是这样,您可以根据该方向设置初始UI

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

此代码示例来自下面Kendall的答案,为完整起见添加到此处:

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

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

上注册加速计读数作为对您评论的回应,我认为我最好将代码放在这里,而不是放在评论中(尽管丹尼尔确实值得表扬):

在ApplicationIDFinishLaunching中:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];
然后,您只需要调用以下方法:

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

莫特,这些答案似乎有点像是在转移视线;我不明白为什么不能对UIViewController类使用以下内置方法:

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {}
此方法在旋转发生后自动调用(而不是使用shouldAutorotateToInterfaceOrientation,它只告诉您旋转即将发生)。方便的是,变量“fromInterfaceOrientation”包含前面的方向。正如文档中所说的,您可以假设视图的interfaceOrientation属性已经设置为新方向,这样您就有一个方法可以访问旧方向和新方向

如果我错过了什么,而你已经拒绝使用这种方法,我道歉!在上面的方法中免费提供“previous orientation”时,您正在为“previous orientation”创建和存储一个变量,这似乎很奇怪


希望有帮助

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

根据您的情况,一个更简单的选项可能是UIViewController类的interfaceOrientation属性。这在旋转前是正确的

如果您需要确定指向的方向,请使用此选项来确定UI的方向

不是100%确定这是对的,但我的脑子里想不出来:

[[[UIApplication sharedApplication] statusBar] orientation]

下面是一种在应用程序首次加载且UIDeviceOrientation设置为UIDeviceOrientationUnknown时获取方向的方法。可以查看旋转视图的变换特性

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;
}

在ApplicationIDFinishLaunching期间,[UIDevice currentDevice]。方向是UIDeviceOrientationUnknown我不知道如何使用PerformSelect:afterDelay。你能给出一个代码示例吗?我试过你说的,但甚至[self-performSelector:@selector(getOriented)with-Object:nil afterDelay:10.0f];没有任何效果你说的“没有任何效果”是什么意思?您的意思是延迟后仍然是
UIDeviceOrientationUnknown
?在启动期间,您可能需要调用
[[UIDevice currentDevice]BegingeratingDeviceOrientationNotifications]
,以确保方向更新。是的,我的意思是延迟后它仍然是UIDeviceOrientationUnknown。[[UIDevice currentDevice]BegingeratingDeviceOrientationNotifications]正在-(void)ApplicationIDFinishLaunching:(UIApplication*)应用程序中调用{您是否建议我需要更早地激活它?我尝试了您所说的,但甚至[self-PerformsSelector:@selector(getOriented)with Object:nil afterDelay:10.0f];没有任何效果十秒钟后调用时的方向是什么?似乎十秒钟后应该设置方向…或者在那时,只需询问主视图控制器其方向是什么。如果我计划旋转接口,则UIDeviceOrientationUnknown将起作用,我不想这样做谢谢!我不知道htat字段的存在-我使用的是UIDevice的方向,这没有多大帮助。这就是为什么***s.O Rocks!***…要用Nugging Futz来解决一个“咳嗽”的简单方向问题…没有线索…搜索会找到delany的答案。这是gold!它会给你一个视图的方向。我使用了
 UIDeviceOrientationIDChangeNotification
检测我以前的方向。