【问题标题】:Height and width on iPhone (/iPad)iPhone (/iPad) 上的高度和宽度
【发布时间】:2010-10-19 19:33:33
【问题描述】:

这只是一个测试应用程序,只有一个 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

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

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

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

【问题讨论】:

  • 您使用的是哪个 SDK 版本?
  • 为什么要在 AppDelegate 中这样做?为了解决这个问题,我在 AppDelegate 中创建了一个 BOOL,它是 False,直到调用该方法并更改为 TRUE。然后在我的 MainVC 的 viewWillLoad 中,我启动了一个计时器来检查 AppDelegate BOOL 是否为 TRUE。如果是我触发显示警报的方法。为了使它看起来更好,我还在我的 MainVC 上显示默认图像,直到出现消息。这似乎是一种 hacky 方法,但我不必总是显示警报视图,所以我也检查一下。

标签: iphone objective-c ipad interface uiwindow


【解决方案1】:

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

iOS 中的应用程序通常在 纵向模式以匹配方向 的主屏幕。如果你有一个 纵向运行的应用程序 和横向模式,您的应用程序 应始终以纵向模式启动 最初,然后让其查看 控制器将界面旋转为 需要根据设备的 方向。如果您的应用程序运行 但是,仅在横向模式下,您 必须执行以下步骤才能 让它在风景中发射 最初的方向:

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

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

  • 覆盖视图控制器的 shouldAutorotateToInterfaceOrientation: 方法并仅返回 YES 所需的横向和否 用于纵向。

重要提示:前面的步骤假设 您的应用程序使用视图控制器 管理其视图层次结构。看法 控制器提供了一个显着的 处理基础设施的数量 方向变化以及其他 复杂的视图相关事件。如果你的 应用程序未使用视图 控制器——可能是这样的 游戏和其他基于 OpenGL ES 应用程序——您负责 旋转绘图表面(或 调整你的绘图命令)为 需要展示您的内容 横向模式。

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

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

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

【讨论】:

  • 非常好的答案,所以我会接受它并开始另一个赏金(虽然不是 500 :\),但我可以将它奖励给你,但我个人更喜欢 Deniz 的答案,所以他得到了赏金.你很好地解释了为什么会发生这种情况,这对我来说真的很有用,如果我现在可以分红,我会的。
  • iPad 是一个例外,因为它的主屏幕可以旋转到横向。
【解决方案2】:

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

希望这会有所帮助。

【讨论】:

  • 感谢您解释 UIAlertView 的条款并说出我应该做什么。
  • 在找到此解决方案之前,我花了很长时间尝试解决此问题。把 [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];因为我的 loadView 的第一行完成了这项工作。谢谢!
  • 我想我刚刚失去了 2 小时试图让我的 iPad 应用程序 (iOS5) 仅以横向启动。这行得通,非常感谢。
【解决方案3】:

使用视图的边界

【讨论】:

    【解决方案4】:

    窗口总是会给出纵向的尺寸。总是。

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

    【讨论】:

    • 我刚刚这样做了,它正确地改变了状态栏差异(20像素),但它仍然没有切换宽度和高度。
    • 横屏时宽度还是768(横屏时屏幕高度为1024),竖屏反之
    • 使用边界,而不是视图的框架来获得正确的坐标
    【解决方案5】:

    尝试在 info.plist 文件中将UISupportedInterfaceOrientations 设置为UIInterfaceOrientationLandscapeLeft,而不是手动弄乱状态栏。然后,应用程序应该在您启动后全部设置好。

    手动设置状态栏方向有点“低级”。您的视图控制器还需要在 shouldAutorotateToInterfaceOrientation 实例方法中返回 UIInterfaceOrientationLandscapeLeft

    【讨论】:

    • 请重新阅读我的问题 :) 你认为你的建议会起作用,但事实并非如此。
    • 为什么没有 UIViews?据我所知,你总是应该在你的窗口中有一个容器 UIView 。您没有将小部件视图直接放在窗口内还是什么?
    • 在我真正的应用程序中(我在这个问题中谈到的只是试图让它工作)我有一个子类 UIViewController,当我使用窗口在 App Delegate 中添加它的视图时。 frame 作为视图的框架,它添加了具有纵向模式尺寸的视图(因此视图的底部被切断并且右侧有一个间隙)
    • 它只是拒绝正确的window.frame大小,它应该在界面旋转时转置宽度和高度,但是由于windows frame.size不正确,这意味着子视图的frame.size是错误的,所以是子视图的子视图。
    • 你确实在 UIViewController 中实现了 shouldAutorotateToInterfaceOrientation 吗?
    【解决方案6】:

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

    • 在 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 上虽然警报如你所说以纵向模式显示。当我将视图添加回来时,警报会根据需要以横向模式显示。

    【讨论】:

      【解决方案7】:

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

      总之长话短说,我将 plist 从 UIInterfaceOrientationLandscapeLeft 更改为 UIInterfaceOrientationLandscapeRight 并将我的 UIViewController 方法更改为:

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

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

      如果这能解决您的问题,请告诉我

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多