简体   繁体   English

获取iPad应用的发布方向

[英]Get launch orientation of iPad app

In my iPad app, I need to run some layout code to set the proper layout depending on the orientation. 在我的iPad应用程序中,我需要运行一些布局代码,以根据方向设置正确的布局。 By default, the layout is configured for the landscape orientation, so in the case that the app starts in portrait mode, I need to take extra action to configure the views properly for display in portrait. 默认情况下,布局是针对横向方向配置的,因此在应用程序以纵向模式启动的情况下,我需要采取额外操作来正确配置视图以便以纵向显示。

In my -application:didFinishLaunchingWithOptions: method, I check the orientation using [[UIDevice currentDevice] orientation] . 在我的-application:didFinishLaunchingWithOptions:方法中,我使用[[UIDevice currentDevice] orientation]检查[[UIDevice currentDevice] orientation] The problem here is that it always returns portrait even if the app is starting in landscape. 这里的问题是,即使应用程序以横向方式启动,它也始终返回纵向。 Is there any way around this? 有没有办法解决?

This is expected behavior. 这是预期的行为。 Quoth the UIViewController documentation : 参阅UIViewController文档

Note: At launch time, applications should always set up their interface in a portrait orientation. 注意:在启动时,应用程序应始终以纵向方式设置其界面。 After the application:didFinishLaunchingWithOptions: method returns, the application uses the view controller rotation mechanism described above to rotate the views to the appropriate orientation prior to showing the window. application:didFinishLaunchingWithOptions:方法返回后,应用程序使用上述视图控制器旋转机制在显示窗口之前将视图旋转到适当的方向。

In other words, as far as the device is concerned the orientation is portrait while the application is launching. 换句话说,就设备而言,在应用程序启动时,方向纵向。 At some point after application:didFinishLaunchingWithOptions: it will detect the different orientation and call your shouldAutorotateToInterfaceOrientation: method and then your other view rotation methods , which you should handle as normal. application:didFinishLaunchingWithOptions:之后的某个时刻application:didFinishLaunchingWithOptions:它将检测不同的方向并调用你的shouldAutorotateToInterfaceOrientation:方法,然后调用你应该正常处理的其他视图旋转方法

This is the best way to check for orientation on launch. 这是检查发布方向的最佳方法。 First, create a new method in your AppDelegate that checks the orientation: 首先,在AppDelegate中创建一个检查方向的新方法:

-(void)checkLaunchOrientation:(id)sender{

     UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;    
     BOOL isLandscape = UIDeviceOrientationIsLandscape(self.viewController.interfaceOrientation);

     if (UIInterfaceOrientationIsLandscape(orientation) || isLandscape) {
       //do stuff here
     }
}

At the end of -application:didFinishLaunchingWithOptions: run -application:didFinishLaunchingWithOptions: 结束-application:didFinishLaunchingWithOptions:运行

        [self performSelectorOnMainThread:@selector(checkLaunchOrientation:) withObject:nil waitUntilDone:NO];

Use self.interfaceOrientation in your view controller - it's a property of UIViewController that is set by iOS for you, and in some cases is more reliable than [[UIDevice currentDevice] orientation] . 在视图控制器中使用self.interfaceOrientation - 它是UIViewController的一个属性,由iOS为您设置,在某些情况下比[[UIDevice currentDevice] orientation]更可靠。

Here's a detailed description: http://bynomial.com/blog/?p=25 以下是详细说明: http//bynomial.com/blog/?p = 25

As mentioned in a blog post above, there is a set of macros for testing orientation. 正如上面的博客文章中所提到的,有一组用于测试方向的宏。 That blog post however mentions UIDeviceOrientationIsPortrait. 然而,该博客文章提到了UIDeviceOrientationIsPortrait。 I like the following below, it's a minor twist. 我喜欢下面的内容,这是一个小小的转折。

if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
{
  NSLog(@"Portrait");
}
else
{
  NSLog(@"Landscape");
}

An observation I've made is that you can't call this code in a table view, pushed on to a Navigation Controller embedded in the split view controller. 我做的一个观察是你不能在表视图中调用这个代码,推到嵌入在拆分视图控制器中的导航控制器。 So in other words you can't call it from the master view controller. 换句话说,你不能从主视图控制器调用它。 You have to replace the "self.interfaceOrientation" with splitviewcontroller.interfaceOrientation, assuming you maintain a reference to the parent split view controller. 假设您维护对父拆分视图控制器的引用,则必须使用splitviewcontroller.interfaceOrientation替换“self.interfaceOrientation”。

Use the status bar orientation instead to detect it. 而是使用状态栏方向来检测它。

UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; UIInterfaceOrientation orientation = [UIApplication sharedApplication] .statusBarOrientation;

then perform the if's on the "orientation" you have obtained from above. 然后在你从上面获得的“方向”上执行if。

So the question is about checking orientation at startup. 所以问题是关于在启动时检查方向。 The answer is sadly "You can't". 答案很遗憾“你不能”。

But AFTER startup, you can check orientation the normal way (as others have described). 但启动 ,你可以检查方向正常方式(如其他人所描述的)。

If anyone else comes here looking for an answer, simply stop looking since, at startup the orientation variable is not set (all views frames/bounds also report being in portrait even if they aren't). 如果有其他人来这里寻找答案,只需停止查看,因为在启动时未设置方向变量(所有视图框架/边界也报告为纵向,即使它们不是)。

It's not true that you can't figure out the launch orientation, it is true that it's a pain in the rear to do so. 你无法弄清楚发射方向是不正确的,这样做确实是后方的痛苦。

here's what you need to do. 这是你需要做的。

your first UIViewController needs to have some special logic to nab the information you'd like. 你的第一个UIViewController需要一些特殊的逻辑来获取你想要的信息。
you might even want to create a UIStartupController just for these purposes if it's that important to your flow. 你可能甚至想为这些目的创建一个UIStartupController,如果它对你的流程很重要的话。
in the case of my project, we already had such a startup controller present. 在我的项目中,我们已经有了这样的启动控制器。

all you need is the following code 您只需要以下代码即可

-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  if (self) {
    self.launchOrientation = UIDeviceOrientationUnknown;
  }
  return self;
}

-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                duration:(NSTimeInterval)duration
{
  [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

  if (self.launchOrientation == UIDeviceOrientationUnknown && duration > 0)
    self.launchOrientation = UIInterfaceOrientationPortrait;
  else
    self.launchOrientation = toInterfaceOrientation;
}

basically, if we're not launching in UIInterfaceOrientationPortrait, the first rotation callback sequence will actually reveal the launch orientation. 基本上,如果我们没有在UIInterfaceOrientationPortrait中启动,第一个旋转回调序列将实际显示启动方向。
if launched in UIInterfaceOrientationPortrait, then we need to check that the first rotation's duration is non zero, and then we know that it was launched from portrait. 如果在UIInterfaceOrientationPortrait中启动,那么我们需要检查第一个旋转的持续时间是否为非零,然后我们知道它是从肖像启动的。

You want to make sure you set the proper keys in your Info.plist to allow for the orientations you want: 您需要确保在Info.plist中设置正确的密钥以允许所需的方向:

UISupportedInterfaceOrientations
    UIInterfaceOrientationPortrait
    UIInterfaceOrientationPortraitUpsideDown
    UIInterfaceOrientationLandscapeLeft
    UIInterfaceOrientationLandscapeRight

Not that you need another answer, but I thought I should add that you almost never want to use [[UIDevice currentDevice] orientation] . 并不是说你需要另一个答案,但我想我应该补充说你几乎不想使用[[UIDevice currentDevice] orientation] That method returns the orientation of the device, which isn't necessarily the same as the orientation of the interface. 该方法返回设备的方向,该方向不一定与接口的方向相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM