【问题标题】:Why in iOS 8 my app at launch take wrong orientation?为什么在 iOS 8 中我的应用启动时方向错误?
【发布时间】:2014-11-09 07:17:21
【问题描述】:

我的应用到 iOS 7 都可以正常工作。我今天用 Xcode 6 尝试了它,当我运行它时,我有一个令人讨厌的惊喜:(:

您可以看到 Xcode 现在绘制我的 viewController 就好像它处于纵向模式,但您可以看到它处于横向模式。

你知道 iOS 8 有什么变化吗? :/ 我使用了以下定位方法:

  • (NSUInteger)支持的接口方向
  • (BOOL)应该自动旋转
  • (BOOL) 应该自动旋转到接口方向:(UIInterfaceOrientation)接口方向

编辑:

我才发现这个方法:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{
 return UIInterfaceOrientationMaskLandscape;
}

现在我的第一个视图控制器可以正常工作:)。问题是当我显示一个模式(改变 UIInterfaceOrientationMaskAll 中的方法集)时,重新制作了屏幕截图的丑陋效果。 正是我在这种模式下改变了我的方法:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if(self.restrictRotation)
    {
        return UIInterfaceOrientationMaskLandscape;
    }    
    else
    {
        return UIInterfaceOrientationMaskAll;
    }
}


// THIS IS A DELEGATE OF MODAL VIEW CONTROLLER
- (void)updateInterfaceAfterDocumentPreviewViewController
{
    NSLog(@"updateInterfaceAfterDocumentPreviewViewController");

    [[UIApplication sharedApplication]     setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];

    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    appDelegate.restrictRotation = YES;
}

【问题讨论】:

  • 在真机上试用。同样的问题?
  • 不幸的是:(
  • 据我所知,iOS 8 不再使用自动旋转和方向 API。每个方向变化只是一个动画边界变化。
  • 感谢您对 Legoless 的评论,请看我对 mc01 的回答。
  • 我在许多第三方应用程序(例如 Reeder)中看到了同样的情况。

标签: ios ipad cocoa-touch uiinterfaceorientation


【解决方案1】:

请尝试以下代码

AppDelegatedidFinishLaunchingWithOptions

self.window.rootViewController = self.viewController;

[self.window makeKeyAndVisible];

[self.window setFrame:[[UIScreen mainScreen] bounds]]; //Add

【讨论】:

    【解决方案2】:

    问题似乎是设置窗口时的调用顺序。在应用程序委托的didFinishLaunchingWithOptions 方法中分配rootViewController 之前,您需要调用makeKeyAndVisible。以下作品:

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [self.window makeKeyAndVisible];
    self.window.rootViewController = self.myMainViewController;
    

    但是如果你把顺序改为:

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = self.myMainViewController;
    [self.window makeKeyAndVisible];
    

    你得到你正在经历的行为。

    【讨论】:

    • 我遇到了完全相同的问题。这个解决方案对我有用。谢谢!
    • 这是否记录在某处?这对我来说似乎是一个错误,但它仍然有效。
    【解决方案3】:

    我在“加载屏幕”中遇到了同样的问题。这对我有用。 (请注意:我的 App 仅支持 iOS 7 或更高版本,横向模式。):

        CGRect theFrame = self.view.frame;
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
            CGRect screenBounds = [[UIScreen mainScreen] bounds];
            theFrame.origin = CGPointZero;
            theFrame.size.width = screenBounds.size.height;
            theFrame.size.height = screenBounds.size.width;
        }
    
        NSLog(@"%@", [NSNumber valueWithCGRect:theFrame]);
        self.loadingScreen = [[UIView alloc] initWithFrame:theFrame];
    

    如果您的应用支持纵向,请参考 Mike Hay 的回答以及“计算正确 applicationFrame 的漫长方法”: https://stackoverflow.com/a/18072095/4108485

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      查看您的 .plist 文件。

      1. 确保将“初始界面方向”设置为您想要的方向。
      2. 在“支持的界面方向”中,将首选方向作为列表中的第一个条目(看起来苹果更改了此顺序)。

      【讨论】:

        【解决方案5】:

        我遇到了类似的问题,我无法显示正确的启动图像(我有两个用于 iPad,Default-Portrait.png 和 Default-Landscape.png),我也无法获得应用程序本身在启动图像消失后自动定向。

        解决启动图像的问题:

        • 转到项目的自定义 iOS 目标属性部分(单击项目文件列表顶部的项目图标,它应该是您看到的第一个部分)。
        • 在该表中添加一行名为“Launch image”(应自动填充)并在右侧列中输入“Default” 作为字符串。
        • 确保您的启动图像遵循 Apple 的文件名指南(即:Default-568@2x、Default@2x 等) check this SO answer

        首先解决 ViewController 的应用方向问题:

        • 转到您的项目 plist 文件(应为“YourApp-Info.plist”)
        • 添加一行并输入“支持的界面方向”
        • 添加您的应用支持的方向

        【讨论】:

          【解决方案6】:

          检测方向的方法是deprecated in iOS8(但现在仍然允许)。 它被大小类和Trait Collections 的概念所取代。

          (奇怪的是,我现在似乎无法在 Apple 的在线文档中找到 Size Class Reference - 我发誓它以前就在那里 - 也许在 XCode 中)。见here for WWDC videos.

          无论如何,Interface Builder 中有一个复选框,上面写着“Use Size Classes”。 你可以检查一下。关掉它看看是否有帮助?

          【讨论】:

          • 没什么变化 :(。在我看来,这是 UIWindow 的问题,因为如果我设置视图的 backgroundColor,我总是看到 UIWindow 的黑色。另外,如果我打印窗口的框架......它是正确
          • 嗯。当您在横向和纵向之间更改模拟器方向时,它会保持这种状态吗?还是只有当它开始运行时?你在使用自动布局吗?也许是一些限制?
          • 我在这个项目中没有使用自动布局,如果我在横向模式下运行应用程序,应用程序可以正常工作,相反,如果我在纵向模式下运行应用程序,应用程序会像附加的屏幕截图一样显示(必须以横向显示)。如果我在 info.plist 中更改设备方向并仅放置横向,则它可以工作,但我还需要纵向以在两个方向上显示 qlpreviewcontroller。
          【解决方案7】:

          老派解决方案:

          BOOL portrait;
          BOOL iOS8OrLater = ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0);
          if (iOS8OrLater) {
              CGFloat height = CGRectGetHeight(self.view.frame);
              CGFloat width = CGRectGetWidth(self.view.frame);
              if (width / height > 1.0) {
                  portrait = NO;
              } else {
                  portrait = YES;
              }
          } else {
              portrait = UIInterfaceOrientationIsPortrait(self.interfaceOrientation);
          }
          if(portrait) {
              [self layoutPortrait];
          } else {
              [self layoutLandscape];
          }
          

          你可以在 viewWillLayoutSubviews 中调用这个

          【讨论】:

            【解决方案8】:
            UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
            
            if( UIDeviceOrientationIsLandscape( currentOrientation ) )
            {
                if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
                {
                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
            
                    // -- Fix for rotation issue for ios 8
                    if( IS_IOS_8_OR_LATER )
                    {
                        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPad"
                                                                             bundle: nil];
                        // -- Set frame of nav controller
                        UINavigationController *nc = [storyboard instantiateViewControllerWithIdentifier:@"NavController"];
            
                        self.window.rootViewController = nc;
            
                        [self.window setFrame:[[UIScreen mainScreen] bounds]];
            
                        // -- Set fame of home view controller
                        UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"Home"];
            
                        self.window.rootViewController = vc;
            
                        [self.window makeKeyAndVisible];
            
                        [self.window setFrame:[[UIScreen mainScreen] bounds]];
                    }
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-10-26
              • 1970-01-01
              • 2020-08-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多