UIViewController displayed sideways on AirPlay screen when launched from landscape iPad

寵の児 提交于 2020-01-01 06:08:06

问题


I'm attempting to display a full screen, 16:9, UIViewController on an external display using AirPlay.

The goal here is to replace AirPlay mirroring with a custom view controller that will span the full size of the external screen.

Everything seems to work great when the screen connects while the iPad is in portrait mode. When it connects in landscape, the UIViewController shows up sideways on the external display and only fills half the screen.

In order to this I'm adding my UIViewController to the attached AirPlay UIScreen.

-(void) screenConnected:(NSNotification * ) notification {

    UIScreen * screen = [notification object]; //this should be the airplay display
    UIWindow * window = [[UIWindow alloc] initWithFrame:screen.bounds];
    [currentWindow setScreen:screen];
    UIViewController * controller = [_delegate createControllerForAirplayDisplay:window];
    [window setHidden:NO];
    [window setRootViewController:controller];

}

This seems to work fine, I see a full screen display on the iPad as well as the AirPlay TV.

Where I'm seeing an issue is when the AirPlay display is connected while the iPad is in landscape mode. When this happens the AirPlay display renders the UIViewController sideways and in what looks like portrait mode.

Screen connected in portrait:

Screen connected in landscape, content is sideways and only rendered on half the display:

I've attempted rotating the UIWindow and UIViewController using CGAffineTransformMakeRotation, this does fix the orientation but the view is not centered inside the AirPlay display.

Edit

Filed an issue with Apple related to this, rdar://20817189. I will update this if/when I hear back.


回答1:


I found this in the documentation: https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/WindowAndScreenGuide/UsingExternalDisplay/UsingExternalDisplay.html

Important: Be sure that your app sets the status bar orientation correctly. Because the external display can’t read the host device’s accelerometer to respond to changes in orientation, it relies instead on the status bar orientation, as set in your app.

The external UIWindow take the orientation from current device, in this case landscape orientation. So, when you set the frame of your rootViewController, for example (0, 0, 1270, 840) the origin is on top-right corner of your Tv.

You have to force UIWindow in portrait orientation. I solved this issue with this code on AppDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)_window {
if ([UIScreen mainScreen] == _window.screen || !_window) {
    return UIInterfaceOrientationMaskAll;
}else {
    return UIInterfaceOrientationPortrait;
}
}



回答2:


Having your shouldAutorotateToInterfaceOrientation method always return YES should sort it out for you.




回答3:


Airplay windows set to Portrait Mask will never rotate. The default status bar is Portrait so the rotation value is based off this. Here is a code example that works (Assuming you've stored your Airplay UIWindow as self.secondWindow on your AppDelegate when it connects)

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if(window == self.secondWindow){
        return UIInterfaceOrientationMaskPortrait;
    }
    return UIInterfaceOrientationMaskAll;
}


来源:https://stackoverflow.com/questions/30040055/uiviewcontroller-displayed-sideways-on-airplay-screen-when-launched-from-landsca

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!