When using the external VGA Adapter, the device as two windows that you must add separate views to. After an entire day attempting to capture all events from one window and attempting to pass them to the other window, I decided to take a more brute force method. Take a screen capture every 1/4 second and display it on the external display.
The steps are below.
1. Create a UIViewController with a XIB and call it ExternalDisplayViewController.
2. In Interface Builder add a single UIImageView and set the View Mode to Aspect Fit.
3. Add a property to the ExternalDisplayViewController.h. Don't forget to "Wire" it up in interface builder.
4. Modify the AppDelegate.h file accordingly.
4. Modify the AppDelegate.h file accordingly.
#import <UIKit/UIKit.h> @class ExternalDisplayViewController; @interface MyAppDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate> { UIWindow *deviceWindow; NSArray *screenModes; UIScreen *externalScreen; ExternalDisplayViewController *externalVC; } @property (nonatomic, retain) NSTimer *repeatingTimer; @property (nonatomic, retain) IBOutlet UIWindow *deviceWindow; @property (nonatomic, retain) IBOutlet UIWindow *externalWindow; - (void) takeCapture:(NSTimer*)theTimer; @end
5. Modify the MainWindow.xib file. Add a second window (that will dsplayed on the external display). Don't forget to "Wire" two windows to the new properties.
6. Add the Quartz Framework to your project and add the import line to the AppDelegate.m file.
6. Add the Quartz Framework to your project and add the import line to the AppDelegate.m file.
#import <QuartzCore/QuartzCore.h>
7. Add the following code to your AppDelegate.m didFinishLaunchingWithOptions
if ([[UIScreen screens] count] > 1) { //[self log:@"Found an external screen."]; // Internal display is 0, external is 1. externalScreen = [[[UIScreen screens] objectAtIndex:1] retain]; //[self log:[NSString stringWithFormat:@"External screen: %@", externalScreen]]; screenModes = [externalScreen.availableModes retain]; //[self log:[NSString stringWithFormat:@"Available modes: %@", screenModes]]; // Allow user to choose from available screen-modes (pixel-sizes). UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"External Display Size" message:@"Choose a size for the external display." delegate:self cancelButtonTitle:nil otherButtonTitles:nil] autorelease]; for (UIScreenMode *mode in screenModes) { CGSize modeScreenSize = mode.size; [alert addButtonWithTitle:[NSString stringWithFormat:@"%.0f x %.0f pixels", modeScreenSize.width, modeScreenSize.height]]; } [alert show]; }
8. Add the following code to your AppDelegate.m file.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { UIScreenMode *desiredMode = [screenModes objectAtIndex:buttonIndex]; externalScreen.currentMode = desiredMode; externalWindow.screen = externalScreen; [screenModes release]; [externalScreen release]; CGRect rect = CGRectZero; rect.size = desiredMode.size; externalWindow.frame = rect; externalWindow.clipsToBounds = YES; externalWindow.hidden = NO; [externalWindow makeKeyAndVisible]; externalVC = [[ExternalDisplayViewController alloc] initWithNibName:@"ExternalDisplayViewController" bundle:nil]; CGRect frame = [externalScreen applicationFrame]; switch(externalVC.interfaceOrientation){ case UIInterfaceOrientationPortrait: case UIInterfaceOrientationPortraitUpsideDown: [externalVC.view setFrame:frame]; break; case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: [externalVC.view setFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.height, frame.size.width)]; break; } [externalWindow addSubview:externalVC.view]; NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(takeCapture:) userInfo:nil repeats:YES]; self.repeatingTimer = timer; } - (void) takeCapture:(NSTimer*)theTimer{ UIView *mainView = [deviceWindow.subviews objectAtIndex:0]; if (mainView) { UIGraphicsBeginImageContext(mainView.frame.size); [mainView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); [externalVC.imgView setImage:viewImage]; UIGraphicsEndImageContext(); } }