【问题标题】:Autorotate issues with second UIScreen on iOS8.0 (and 8.1)iOS8.0(和 8.1)上第二个 UIScreen 的自动旋转问题
【发布时间】:2025-12-06 03:20:08
【问题描述】:

我的应用驱动第二个屏幕(外接显示器),但我看到一些关于旋转的“奇怪”事情(在 iOS7 上不会发生的事情)

如果我以横向启动应用程序(并连接第二个屏幕),然后点击主页按钮将应用程序置于后台,然后重新打开应用程序,则第二个屏幕(连接到显示器)旋转 90 度并且只使用一半的屏幕。没有多少后续轮换可以解决此问题。

我很确定这是一个错误 - 但我很乐意知道其他情况。下面是在一个简单的单视图应用程序中重现它的代码。

谢谢

@interface AppDelegate ()

@property (nonatomic, strong) UIWindow* externalWindow;

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenDidConnect:) name:UIScreenDidConnectNotification object:nil];

    UIScreen* externalScreen = ([UIScreen screens].count > 1 ? [[UIScreen screens] objectAtIndex:1] : nil);
    if (externalScreen)
    {
        [self setupExternalScreen:externalScreen];
    }

    return YES;
}

- (void) screenDidConnect:(NSNotification *)aNotification
{
    UIScreen* externalScreen = (UIScreen*)aNotification.object;
    [self setupExternalScreen:externalScreen];
}

- (void)setupExternalScreen:(UIScreen*)externalScreen
{
    externalScreen.currentMode = externalScreen.preferredMode;

    self.externalWindow = [[UIWindow alloc] initWithFrame:externalScreen.bounds];
    self.externalWindow.screen = externalScreen;
    self.externalWindow.clipsToBounds = YES;
    self.externalWindow.hidden = NO;
    [self.externalWindow makeKeyAndVisible];

    UIViewController* externalViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
    externalViewController.view.backgroundColor = [UIColor redColor];
    self.externalWindow.rootViewController = externalViewController;
}
@end

【问题讨论】:

    标签: ios uiwindow uiscreen


    【解决方案1】:

    好的 - 修复它。

    而不是设置

    self.externalWindow.rootViewController = externalViewController;
    

    相反,只需将视图添加为窗口的子视图(记得在视图控制器对象上保留引用)

    self.externalViewController.view.frame = self.externalWindow.frame;
    [self.externalWindow addSubview:self.externalViewController.view];
    

    我猜视图控制器的东西很混乱.....

    【讨论】:

    • 另一个错误 - 不要将外部 UIWindow 设为“键” - 它会弄乱很多急救人员的东西。
    【解决方案2】:

    另一个似乎可行的解决方案:在窗口的根视图控制器中覆盖 supportedInterfaceOrientationsshouldAutorotate

    - (NSUInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskPortrait;
    }
    
    - (BOOL)shouldAutorotate
    {
        return NO;
    }
    

    【讨论】:

      【解决方案3】:

      我只是改造 UIWindow 来解决它

      CGRect frame = screen.bounds;
      
      if (!self.secondWindow) {
          UIWindow *extWindow = [[UIWindow alloc] initWithFrame:frame];
          self.secondWindow = extWindow;
      }
      
      if ([[[UIDevice currentDevice] systemVersion] integerValue] == 8) {
          CGFloat magicAmount = (frame.size.width - frame.size.height) / 2;
          if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
              float rotation = M_PI_2;
              self.secondWindow.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rotation), magicAmount, magicAmount);
          }
          else if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
              float rotation = -M_PI_2;
              self.secondWindow.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rotation), -magicAmount, -magicAmount);
          }
      }
      

      【讨论】: