【问题标题】:UIScreen applicationFrame returning incorrect rectangle on landscape application launch (iPhone/iPad)UIScreen applicationFrame 在横向应用程序启动时返回不正确的矩形 (iPhone/iPad)
【发布时间】:2010-04-19 02:58:05
【问题描述】:

在横向模式下启动我的 iPad 应用程序时无法获得正确的边界。我在 Info.plist 文件中设置了正确的键,并且我的视图控制器在横向(和纵向,自然)中正确启动。

在我的 applicationDidFinishLaunching: 方法中,我在 3 秒延迟后调用选择器,该方法调用 [[UIScreen mainScreen] applicationFrame],但它返回给我一个纵向框架(即高度 > 宽度)。

有谁知道如何解决这个问题?对我来说,它闻起来像一个错误(如果是这样,我会提交雷达),但如果它是预期的行为,它记录在哪里?

【问题讨论】:

  • 从现在开始我可以只说“不正确的角度”吗?

标签: iphone cocoa-touch uikit ipad device-orientation


【解决方案1】:

我从不依赖[[UIScreen mainScreen] applicationFrame],尤其是在应用启动期间。

在代码中创建视图时,使用超级视图来设置框架。

如果您使用带有“模拟界面元素”的 xib,它们的大小会正确,一切都会很好。

基于 UINavigationController 的应用

对于基于 UINavigationController 的应用程序,直接从self.navigationController.view 抓取框架,不要尝试使用[self loadView]self.view.superview。 UINavigationController 使用“隐藏的”子视图来完成它的工作——所以直接的超级视图将不起作用。

UINavigationController 很特别,因为在应用启动期间,导航控制器会在调用 loadView 后调整您的视图大小。当自动调整大小开始时,您最终会在屏幕底部有一个小边距。

为什么不用 UIScreen

[[UIScreen mainScreen] applicationFrame] 不能可靠地工作(尤其是在横向启动应用时)。我的经验是视图控制器的interfaceOrientation 属性与applicationFrame 方向不匹配。

【讨论】:

  • 这太重要了!谢谢
  • 这很有帮助!如果我早点找到它,我会节省很多时间!谢谢!
【解决方案2】:
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
    bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}

【讨论】:

    【解决方案3】:

    当您以横向方式拿着 iPad 并启动应用程序时,视图控制器最初会看到纵向视图的边界(即使方向报告横向)。然后,视图控制器将收到一条消息,在它出现之前旋转到横向。

    【讨论】:

    • 那么消息发送到视图控制器旋转后,坐标系是否会反映新的方向?比如消息发送后,width > height?
    【解决方案4】:

    当视图控制器处于横向时,这是我获得正确 CGRect 的方式:

    CGRect landscapeBounds;
    if (self.view.frame.size.width < self.view.frame.size.height)
        landscapeBounds = CGRectMake(self.view.frame.origin.y, self.view.frame.origin.x, self.view.frame.size.height, self.view.frame.size.width);
    else
        landscapeBounds = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    

    【讨论】:

      【解决方案5】:

      这是设计的。您应该查询您的 superview 的大小并根据需要进行调整。

      【讨论】:

      • 你能解释一下为什么这样设计(或至少推测)。如果屏幕已经旋转,我觉得给屏幕提供不正确的边界似乎是不合逻辑的。有问题的superview 是我的应用程序的窗口(我也尝试使用它的框架来获得相同的结果)。
      • 原因是窗口可以独立于屏幕旋转。示例:当纵向应用程序启动 YouTube 视频时,主窗口保持纵向,但横向窗口在其上方显示动画。在动画期间,设备应该被视为纵向还是横向? (加速度计方向与窗口方向分开与状态栏方向分开)
      • 我也注意到了这一点,真的很奇怪。感谢您的提醒。
      • 在这种情况下,我的应用程序窗口是我的超级视图,即使它是横向的,它也会报告纵向边界。令人沮丧。但如果需要,我只需要使用[UIDevice orientation] 来交换 w+h。
      • -[UIDevice orientation] 不应用于此目的; -[UIApplication statusBarOrientation] 应改为使用。 UIDeviceOrientation 具有在这种情况下没有意义的其他状态:UIDeviceOrientationUnknownUIDeviceOrientationFaceUpUIDeviceOrientationFaceDown
      【解决方案6】:

      [[UIScreen mainScreen] applicationFrame] 将始终返回纵向矩形,即使应用程序处于横向模式。这与 UIWindow 从不 实际旋转,而只是更改 rootViewController.view 的变换这一事实有关。

      为确保您可以在纵向和横向模式下打印根视图对象,您将看到如下内容:

      肖像:

      <UIView: 0x96290e0; frame = (0 20; 768 1004); ...
      

      风景:

      <UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...
      

      【讨论】:

        【解决方案7】:

        因此,根据 Apple 的指南,添加一个启动图像并为其赋予后缀 -568h。

        我不明白为什么有头脑的人会让系统设置依赖于图形;但我刚刚测试过,它确实有效。

        Here is the spot that taught me after a quick search我没有在上面看到这个答案,认为它对某人有用。

        S

        【讨论】:

          【解决方案8】:

          在 Cordova 插件中使用 dismissViewControllerAnimated 关闭视图时,我遇到了同样的问题。 我修改了 MainViewController 中 viewWillAppear 方法的 SingingAtom 代码,在关闭模式视图后调整了大小:

          - (void)viewWillAppear:(BOOL)animated
              {
              CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
              UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
              if (UIDeviceOrientationLandscapeLeft == orientation || 
                  UIDeviceOrientationLandscapeRight == orientation)
                      {
                      if (appFrame.size.width < appFrame.size.height)
                          {
                          appFrame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width);
                          }
                  }
              self.view.frame = appFrame;
              [super viewWillAppear:animated];
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-11
            • 2021-02-07
            • 2012-03-06
            相关资源
            最近更新 更多