9

a design / architectural question on airplay. I have setup an external display in the AppDelegate:

UIScreen *externalScreen = UIScreen.screens.lastObject;
self.externalWindow = [[UIWindow alloc] initWithFrame:externalScreenFrame];
self.externalWindow.screen = externalScreen;
self.externalWindow.backgroundColor = [UIColor redColor];

Works fine, TV shows an empty screen in red. Now I have a ViewController with a bunch of subviews, and one view should be shown on the device and the external screen. If I try this in ViewController.m:

[_appDelegate.externalWindow addSubview:self.deviceAndTVView];

deviceAndTVView will only show on the external screen, not on the device anymore. What I would need is to have deviceAndTVView on the device, updating itself on touches / user interaction, and mirror those updates on the external screen.

Which is the right path to accomplish that?

Thanks for reading! m

marimba
  • 3,116
  • 5
  • 26
  • 29

2 Answers2

15

The technology called AirPlay mirroring is poorly named. It actually operates in two modes, one where the entire iOS device is mirrored to the AirPlay device, and in another mode where once the mirroring AirPlay device is connected, the developer has two UIWindow/UIScreen's to work with.

You are using the latter mode, which is often referred to as "mirroring", but really you have a completely separate window/screen to manage and there should be better terminology to refer to this mode of operation.

What you describe doing above is basically moving a UIView from the device window to the AirPlay window, and it's working exactly as it should!

There is no technical way for you to have a single instance of a UIView show on both of these windows - it will exist in one UIView hierarchy or the other, but not both at the same time. In other words, if you want the same thing to show on both screens, you need to create two instances of the same UIView, and add them respectively to the two windows, and then update both of them as they change.

While this may not be the super-convienent "mirroring" you were expecting, it's probably be a good thing because your UIView may have different aspect ratio on the device than it does on the AirPlay device. By having two different views, showing the same content, you can adjust the sizing of the AirPlay view to best use of the available resolution of the device.

Rob Reuss
  • 1,400
  • 10
  • 20
  • Thanks, you are right. Creating two views and manage them in parallel is the only option. For anyone interested, this is described in Apples documentation [here](http://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingWindows/CreatingWindows.html#//apple_ref/doc/uid/TP40009503-CH4-SW9) under "Displaying Content on an External Display". – marimba Jun 05 '12 at 14:27
  • Since iOS 7 you should be able to use the snapshotting API to show a particular UIView on the other screen – jjxtra Mar 09 '15 at 02:07
  • Hey @Rob the other day I saw one app "Shiftscreen 4X" that the developer is using the same view in the 2 screen and not just replicate (you can see that is the same view when using the web browser). I don't know how he managed to do that, and I'm going crazy trying to find one way to do this. Do you think you know how he managed to do this? – Tiago Mendes May 25 '22 at 18:48
1

I can think of a couple of ways of doing this. Have you looked at using KVO for this? Both the local and external views could observe whatever model or controller is driving their content.

quellish
  • 21,123
  • 4
  • 76
  • 83