镜像视图控制器到外部显示器



我正在尝试在代码中,将我在iPad应用程序上的视图镜像到外部显示器。 在AppDelegate didFinishLaunching中,我有:

 if ([[UIScreen screens] count] > 1)
    {
        UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
        NSString *availableModeString;
        for (int i = 0; i < secondScreen.availableModes.count; i++)
        {
            availableModeString = [NSString stringWithFormat:@"%f, %f",
                                   ((UIScreenMode *)[secondScreen.availableModes objectAtIndex:i]).size.width,
                                   ((UIScreenMode *)[secondScreen.availableModes objectAtIndex:i]).size.height];
            [[[UIAlertView alloc] initWithTitle:@"Available Mode" message:availableModeString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
            availableModeString = nil;
        }
        // undocumented value 3 means no overscan compensation
        secondScreen.overscanCompensation = 3;
        self.secondWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 1280, 720)];
        self.secondWindow.backgroundColor = [UIColor blueColor];
        self.secondWindow.screen = secondScreen;
        ViewController *viewController = [[ViewController alloc] init];
        self.secondWindow.rootViewController = viewController;
        self.secondWindow.hidden = NO;
    }

外部显示器中显示的只是代码中设置的蓝色背景颜色。

我可以使用以下方法在iPhone 6上镜像视图:

@interface MirrorViewController ()
@property (nonatomic, retain) UIView *viewToMirror;
@property (nonatomic, retain) UIView *snapshotView;
@end
@implementation MirrorViewController
- (instancetype)initWithViewToMirror:(UIView*)view
{
    self = [super initWithNibName:nil bundle:nil];
    if (self == nil) return nil;
    self.viewToMirror = view;
    return self;
}
- (void)viewDidLoad
{
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)update
{
    [self.snapshotView removeFromSuperview];
    self.snapshotView = [self.viewToMirror snapshotViewAfterScreenUpdates:NO];
    [self.view addSubview:self.snapshotView];
}
@end

以下是如何在didFinishLaunch代码中使用它的方法:

if ([[UIScreen screens] count] > 1)
{
    UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
    // [...]
    self.secondWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 1280, 720)];
    self.secondWindow.backgroundColor = [UIColor blueColor];
    self.secondWindow.screen = secondScreen;
    MirrorViewController *mirrorViewController = [[MirrorViewController alloc] initWithViewToMirror:self.window.rootViewController.view];
    self.secondWindow.rootViewController = mirrorViewController;
    self.secondWindow.hidden = NO;
}

不过,我还没有在带有外部显示器的iPad上对其进行测试,因为我没有装备。

首先检查应用启动时是否存在外部显示器。如果第二个显示器可用,它将为其创建一个窗口。我在应用程序中使用了以下代码。

(void)checkForExistingScreenAndInitializeIfPresent
{
    if ([[UIScreen screens] count] > 1)
    {
        // Get the screen object that represents the external display.
        UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
        // Get the screen's bounds so that you can create a window of the correct size.
        CGRect screenBounds = secondScreen.bounds;
        self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        self.secondWindow.screen = secondScreen;
        // Set up initial content to display...
        // Show the window.
        self.secondWindow.hidden = NO;
    }
}

通过以下代码注册连接和断开连接通知。

(void)setUpScreenConnectionNotificationHandlers
{
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(handleScreenDidConnectNotification:)
            name:UIScreenDidConnectNotification object:nil];
    [center addObserver:self selector:@selector(handleScreenDidDisconnectNotification:)
            name:UIScreenDidDisconnectNotification object:nil];
}

处理屏幕连接和断开连接通知

(void)handleScreenDidConnectNotification:(NSNotification*)aNotification
{
    UIScreen *newScreen = [aNotification object];
    CGRect screenBounds = newScreen.bounds;
    if (!self.secondWindow)
    {
        self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
        self.secondWindow.screen = newScreen;
        // Set the initial UI for the window.
    }
}
(void)handleScreenDidDisconnectNotification:(NSNotification*)aNotification
{
    if (self.secondWindow)
    {
        // Hide and then delete the window.
        self.secondWindow.hidden = YES;
        self.secondWindow = nil;
    }
}
如果未为显示器创建窗口

,或者创建窗口但不显示窗口,则外部显示器上会显示一个黑字段。

无法保证所有模式在外部显示器中都可用,因此您不应依赖于特定模式的可用性。

在极少数情况下,您可能希望对 overscanCompensation 属性使用不同的值,但这样做总是会导致您必须执行更多工作。例如,如果使用 UIScreenOverscanCompensationInsetBounds ,则必须准备好处理非标准显示大小的边界。

最新更新