iOS:设备在加载时的方向

57

似乎当我的应用程序加载时,它不知道当前的方向:

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
    NSLog(@"portrait");// only works after a rotation, not on loading app
}

当我旋转设备后,方向就正确了。但是当我加载应用程序而未改变方向时,使用 [[UIDevice currentDevice] orientation] 似乎无法知道当前方向。

在我第一次加载应用程序时,是否有其他方法可以检查此问题?


1
请参阅iPhone方向 - beryllium
16个回答

66

编辑: 我误读了你的问题。这将允许您在特定方向中启动应用程序。刚意识到您正在尝试在启动时确定方向。

有一种方法可以在UIApplication上检查状态栏方向:

[[UIApplication sharedApplication] statusBarOrientation];
尝试在plist文件中设置应用程序接受的设备方向。
<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

这将表明您的应用程序支持纵向(home按钮在底部),左横向和右横向。

然后,在您的UIViewControllers中,您需要重写shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)方法,以便在应用程序需要旋转时返回YES:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

     return interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

这会告诉UIViewController,在设备处于支持的方向之一时自动旋转。如果您还想支持倒置方向(Home键在上方的肖像模式),请将其添加到您的属性列表中,并只需从此方法返回YES即可。

让我们知道它的工作原理。


是的,检查statusbarOrientation就是解决问题的关键! - Nic Hubbard
5
对于我来说不起作用,每次都是竖屏。我正在尝试在iPad上测试模拟器。这取决于硬件吗?它会在设备上运行吗? - Nilesh Tupe
shouldAutorotateToInterfaceOrientation 的结果会因根视图控制器是否为导航控制器而有所不同。 - user246672
请查看此帖子。https://dev59.com/nG025IYBdhLWcg3wpHl_#32758397 - jenish
请查看以下解决方案,以确定iOS设备的方向和加载时间... http://jenishshah2311.blogspot.in/2015/09/how-to-determine-ios-device-orientation.html - jenish
显示剩余2条评论

11

我认为这样可以起作用:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;
根据UIDevice参考文献:
引用:
“除非通过调用beginGeneratingDeviceOrientationNotifications启用方向通知,否则此属性的值始终返回0”
我最初认为此属性始终包含当前方向,但显然并非如此。我猜想在其他通常访问方向属性的情况下,后台已经为我们处理了打开通知的操作,因此在应用程序委托中手动执行此操作并不明显。

2
似乎那个方法不起作用,最终我使用了[UIApplication sharedApplication].statusBarOrientation,这个方法可行。 - Nic Hubbard

4

如果您正在寻找Swift 3或4的答案,只需将该代码添加到viewDidLoad()块中即可。

let orientation = UIApplication.shared.statusBarOrientation
if orientation == .portrait {
      // portrait   
} else if orientation == .landscapeRight || orientation == .landscapeLeft{
      // landscape     
}

更新针对IOS 13和Swift 5.x的折旧提醒,请使用以下代码块。

 if #available(iOS 13.0, *) {
        let orientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation
        if orientation == .portrait {
                     // portrait

               } else if orientation == .landscapeRight || orientation == .landscapeLeft{
                     // landscape
               }
    } else {
        // Fallback on earlier versions
        let orientation = UIApplication.shared.statusBarOrientation
        if orientation == .portrait {
                            // portrait

    } else if orientation == .landscapeRight || orientation == .landscapeLeft{
                               // landscape
    }
    }

1
我收到了一条消息,说statusBarOrientation已经被弃用了。也许你可以使用新的值更新你的答案? - Joseph Astrahan

2

目前还没有人提到的一件事是,您正在将UIDeviceOrientation类型存储在UIInterfaceOrientation变量中。它们是不同的,不应该被视为相等。请注意,UIDeviceOrientationLeft等于UIInterfaceOrientationRight(因为界面与设备旋转的方向相反)。


是的,deviceorientation包括面朝下和面朝上。iOS 6是解决设备/界面方向问题的一个垫脚石。iOS < 6非常复杂,而且在iOS 6.0.1中仍然存在很多问题。新的-(BOOL)shouldAutorotate从未被调用,至少在模拟器中是这样的。而shouldAutorotateToInterfaceOrientation过早地被弃用了。 - user246672

2

您可以通过将以下通知插入到

-(void)viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

那么请将以下方法放在你的类中:
-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
    {
         //Do your textField animation here
    }
}

以上方法将检查iPad或iPhone的状态栏方向,并根据其进行所需方向的动画处理。

2

在加载时,设备方向可能是.Unknown.FaceUp。为了确定它是纵向还是横向,我使用statusBarOrientation作为备用方案,如下所示:

    var portraitOrientation = UIDevice.currentDevice().orientation == .Portrait

    if UIDevice.currentDevice().orientation == .Unknown || UIDevice.currentDevice().orientation == .FaceUp {
        portraitOrientation = UIApplication.sharedApplication().statusBarOrientation == .Portrait
    }

这样我就能保证portraitOrientation始终告诉我设备是处于竖屏模式还是横屏模式,即使是首次加载应用程序。


1
为了从状态栏中获取方向,还需要在plist文件中启用所有方向。

1
基于@Marjin的代码,使用Swift 3。
var portraitOrientation = UIDevice.current.orientation == .portrait

if UIDevice.current.orientation == .unknown || UIDevice.current.orientation == .faceUp {
     portraitOrientation = UIApplication.shared.statusBarOrientation == .portrait
}

if(portraitOrientation)
{
     // Portrait
}
else
{

}

0
尝试使用加速度计获取其读数,UIAccelerometer,获取sharedAccelerometer,设置其委托,获取读数,从那里确定方向。

是的,但是旧款iPod Touch没有加速度计,所以这在我的情况下不起作用。 - Nic Hubbard
1
实际上,即使第一代iPod Touch也配备了加速度计。 - Matthias Bauch

0

问题在于[UIDevice currentDevice]orientation]有时会错误地报告设备的方向。

相反,使用[[UIApplication sharedApplication]statusBarOrientation],它是一个UIInterfaceOrientation,因此要检查它,您需要使用UIInterfaceOrientationIsLandscape(orientation)

希望这可以帮助到您。


1
设备方向报告错误的情况是什么?你能举个例子吗? - Victor Engel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接