8

这只是一个测试应用程序,只有一个 AppDelegate 类来创建我所做的只是创建一个基于 Window 的应用程序,将支持的方向设置为仅 info.plist 中的横向,然后添加以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
[application setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];

// Override point for customization after application launch.
UIAlertView *test = [[UIAlertView alloc] initWithTitle:@"hu" message:@"hui" delegate:nil cancelButtonTitle:@"hi" otherButtonTitles:nil];
[test show];
[window makeKeyAndVisible];
    NSLog(@"win %f - %f", window.bounds.size.width, window.bounds.size.height);
return YES;
}

如果没有设置状态栏方向的第一行,即使界面的其余部分在横向左侧,警报视图也会以纵向显示。

无论如何,日志仍然给出:

win 768.000000 - 1024.000000

这是错误的方式(因此当我在我的真实应用程序中添加子视图时,框架不正确)

苹果似乎真的在界面旋转上搞砸了,因为我除了问题什么都没有,我不记得在 iPhone 上发生过任何这种情况,所以请有人告诉我如何解决这个问题。

我会给至少可以解释为什么会发生这种情况并希望能提供解决方案的人提供 500 个声誉(除了我的声誉的 10 个)。

4

7 回答 7

17

我认为iOS Application Programming Guide“Launching in Landscape Mode”主要解释了您的测试应用程序发生了什么:

iOS 中的应用程序通常以纵向模式启动以匹配主屏幕的方向。如果您的应用程序同时在纵向和横向模式下运行,您的应用程序应始终以纵向模式启动,然后让其视图控制器根据设备的方向根据需要旋转界面。但是,如果您的应用程序仅在横向模式下运行,则必须执行以下步骤以使其最初以横向模式启动:

  • 在应用程序的 Info.plist 文件中,添加 UIInterfaceOrientation 键并将其值设置为横向模式。对于横向,您可以将此键的值设置为 UIInterfaceOrientationLandscapeLeft 或 UIInterfaceOrientationLandscapeRight。

  • 以横向模式布置您的视图,并确保其自动调整大小选项设置正确。

  • 覆盖您的视图控制器的 shouldAutorotateToInterfaceOrientation: 方法并仅针对所需的横向方向返回 YES,对于纵向方向返回 NO。

重要提示:前面的步骤假设您的应用程序使用视图控制器来管理其视图层次结构。视图控制器为处理方向变化以及其他复杂的视图相关事件提供了大量的基础设施。如果您的应用程序不使用视图控制器(可能是游戏和其他基于 OpenGL ES 的应用程序的情况),您负责根据需要旋转绘图表面(或调整绘图命令)以在横向模式下呈现您的内容。

就您的测试应用而言,关键部分是最后一部分。您没有视图控制器,因此您完全负责按照您想要的方向设置 UI。这就是您必须手动设置状态栏方向的原因。

我读到第一段说iOS应用程序总是以纵向模式启动,然后根视图控制器旋转它的视图以立即匹配设备方向,并且一旦将其添加到窗口中就没有动画。这意味着 UIWindow 本身不会旋转,因此它的尺寸将始终是纵向的(正如 tadej5553 所说)。此外,所有 UIWindow 子视图的框架也将是纵向的(因为框架总是在父视图的坐标中定义)。因此,无论您如何旋转设备,根视图控制器的框架将始终是纵向的。但是,由于视图的 bounds 属性是根据其自己的坐标定义的,因此高度和宽度应该反映视图的当前方向。

目前尚不清楚您要使用真实应用程序完成什么,但推荐的做法是将视图布局为纵向,然后设置其自动调整大小属性以处理自动旋转(无论是在应用程序启动后立即发生还是稍后发生) .

于 2010-10-22T21:07:47.100 回答
10

UIWindow 对旋转一无所知。旋转方法封装在 UIViewController 中。(自动旋转等)

UIAlertView 使用 UIApplication 的statusBarOrientation属性来选择警报的方向。

// Rotate to a specific orientation.  This only rotates the status bar and updates the statusBarOrientation property.
// This does not change automatically if the device changes orientation.
@property(nonatomic) UIInterfaceOrientation statusBarOrientation;

从 SDK 标头可以看出,statusBarOrientation 不会自动更改。因此,您或 UIViewController(自动旋转)都应该更改此属性。

如果您启动纵向(与 UIWindow 的默认方向一致),并使用shouldAutorotateToInterfaceOrientation并让 UIViewController 处理旋转,它会在每次设备方向更改时更改 UIApplication 的statusBarOrientation 。

但是如果你从横向模式开始,你应该手动设置一次statusBarOrientation

希望这可以帮助。

于 2010-10-22T11:02:01.620 回答
6

使用视图的边界

于 2010-10-26T09:30:51.913 回答
4

窗口将始终给出纵向方向的大小。总是。

但是它的视图会给出正确的测量值(关于方向),所以一定要使用它们。

于 2010-10-19T20:09:59.310 回答
3

与其手动弄乱状态栏,不如尝试在 info.plist 文件中设置UISupportedInterfaceOrientations为。UIInterfaceOrientationLandscapeLeft然后,一旦启动,应用程序就应该全部设置好。

手动设置状态栏方向是一种“低级”。您的视图控制器还需要UIInterfaceOrientationLandscapeLeftshouldAutorotateToInterfaceOrientation实例方法中返回。

于 2010-10-19T19:55:12.750 回答
3

这是我为使其正常工作所做的工作:

  • 在 Info.plist 中,确保具有以下参数:
    • 初始界面方向=横向(右主页按钮)
    • 支持的界面方向
      • 项目 0 = 横向(右主页按钮)
      • 项目 1 = 横向(左主页按钮)
  • 添加一个基于 xib 的视图控制器,其中包含一个自动调整大小的视图(消除调整大小问题等)
    • 注意我在这里使用了带有视图控制器的导航控制器,因为它是我方便的,但我认为这也应该与单个 VC 一起使用。

向您的应用程序委托添加一点代码:

_rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil]; 
_navigationController = [[UINavigationController alloc] initWithRootViewController:self.launcherViewController];
[window addSubview:self.navigationController.view]; //I think this is the key.
[window makeKeyAndVisible];

我认为关键是视图,我在没有它的情况下尝试了它,在 iPhone 上它工作得很好,在 iPad 上,虽然警报如你所说以纵向模式显示。当我将视图添加回来时,警报会根据需要以横向模式显示。

于 2010-10-28T08:00:31.897 回答
0

除了将我的应用程序硬编码为仅横向模式外,我什么都没有。很多时候没有视觉问题,但无法选择底部 20 像素中的按钮。我在主 UIWindow 上做了一个 clipToBounds 并在其图层上添加了一个边框,我可以看到 UIWindow 在状态栏下方。我尝试将我的 UIWindow 的 x 偏移更改为 20(UIWindow 仍然是纵向的,它的内容是横向的)但这意味着我的 UIControllers 被向下移动了 20 个像素(不知道为什么)。尽管这与您的问题不同,但我也发现了与您相同的问题,即打印时的边界和框架似乎是正确的。

无论如何,长话短说,我将我的 plist 从 UIInterfaceOrientationLandscapeLeft 更改为 UIInterfaceOrientationLandscapeRight 并将我的 UIViewController 方法更改为:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
  return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

我所有的问题都消失了。很多时候,我发誓 Apple 的轮换代码中存在错误,结果证明这是我实现某些东西的方式,但我认为这绝对是 Apple 的。

让我知道这是否能解决您的问题

于 2011-02-21T07:50:38.953 回答