Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIViewController displayed sideways on AirPlay screen when launched from landscape iPad

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:

Launched in portrait, displays ok

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

Launched in landscape, displays sideways

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.

like image 938
francis Avatar asked Jan 08 '23 10:01

francis


1 Answers

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;
}
}
like image 76
Martino Bonfiglioli Avatar answered Jan 20 '23 08:01

Martino Bonfiglioli