Ios 镜像ViewController至外部显示器

Ios 镜像ViewController至外部显示器,ios,objective-c,Ios,Objective C,我试图在代码中,让我在iPad应用程序上的视图镜像到外部显示器。在AppDelegate didFinishLaunching中,我有: if ([[UIScreen screens] count] > 1) { UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1]; NSString *availableModeString; for (int i = 0;

我试图在代码中,让我在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;
    }
if([[UIScreen screens]计数]>1)
{
UIScreen*secondScreen=[[UIScreen screens]对象索引:1];
NSString*可用性销毁;
对于(int i=0;i

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

我可以使用以下方法在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
以下是如何在didFinishLaunching代码中使用它:

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
属性使用不同的值,但这样做总是会导致您需要做更多的工作。例如,如果您使用
UIScreenoverscanCompensationInsettBounds
,您必须准备好处理非标准显示大小的界限。

您是说使用视频提供实时提要,还是只是模拟第二个屏幕上的视图?更重要的是,我们是否允许第二个屏幕使用触摸屏来改变第一个屏幕?主要是将iPad屏幕上的内容镜像到苹果电视上,75以高清方式进行,而屏幕周围没有4个栏,这就是从指挥中心进行AirPlay镜像时会发生的情况。嗯……我不确定这应该是什么情况,或者应该如何称呼它?这应该是didLoadView吗?
loadView
在需要加载UIViewController的视图时由UIKit自动调用。实现UIViewController子类并重写loadView,就像我的示例代码一样。我还没有测试过使用snabshotView镜像这样的视图是否有效,但是如果有效,那么代码应该是您所需要的全部:)另外,自从我第一次发布它以来,我对代码做了一些更改。您知道如何将此代码更新到iOS 13吗?
屏幕
设置器已弃用。